Java GridBagLayout无法在组件之间正确分配大小
在我看来,这是一个非常简单的问题。在我看来,这只是对制作Java GridBagLayout无法在组件之间正确分配大小,java,swing,resize,gridbaglayout,Java,Swing,Resize,Gridbaglayout,在我看来,这是一个非常简单的问题。在我看来,这只是对制作GridBagLayout的人的一个重大疏忽 无论如何。我正在使用GridBagLayout为我正在制作的游戏显示一个27x13的格子。我之所以使用这种布局,是因为它能够调整组件的大小,也因为它很容易配置,但有一个小问题。调整瓷砖大小时,如果宽度不是27的倍数,或者高度不是13的倍数,则边框周围会有空白 为了说明我的意思: 当我调整帧的大小,使JPanel内的大小为864x416,是27和13的完美倍数时,它就是这个样子 就是当我调整帧的大
GridBagLayout
的人的一个重大疏忽
无论如何。我正在使用GridBagLayout
为我正在制作的游戏显示一个27x13的格子。我之所以使用这种布局,是因为它能够调整组件的大小,也因为它很容易配置,但有一个小问题。调整瓷砖大小时,如果宽度不是27的倍数,或者高度不是13的倍数,则边框周围会有空白
为了说明我的意思:
当我调整帧的大小,使JPanel
内的大小为864x416,是27和13的完美倍数时,它就是这个样子
就是当我调整帧的大小,使其中的JPanel
大小为863x415,而不是27或13的倍数时的样子
它只是不在瓷砖之间分配额外的像素。我不知道为什么。当我使用它们各自的方法或覆盖它们,甚至使用GridBagLayout
的ipadx
和ipady
约束来摆弄最小/最大/首选大小时,我可以删除空白-但它所做的只是挤压最外层的瓷砖以适应其余部分。您可以在下面的示例代码中看到这一点
这是一个SSCCE:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JPanel {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
}
});
}
static void start() {
JFrame frame = new JFrame("Game");
JPanel newFrame = new MainGameScreen();
frame.getContentPane().add(newFrame);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MainGameScreen extends JPanel {
public MainGameScreen() {
setPreferredSize(new Dimension(864, 551));
setLayout(new GridBagLayout());
setBackground(Color.green);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.ipadx = 0; //Change to 64 to see undesired effects
gbc.ipady = 0; //^
for (int i=0;i<13;i++) {
for (int j=0;j<27;j++) {
gbc.gridx = j;
gbc.gridy = i;
add(new ImagePanel(), gbc);
}
}
}
}
class ImagePanel extends JComponent {
private int r,g,b;
public ImagePanel() {
Random generator = new Random();
r = generator.nextInt(100)+1;
g = generator.nextInt(100)+1;
b = generator.nextInt(100)+1;
}
@Override
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
gr.setColor(new Color(r,g,b));
gr.fillRect(0, 0, getWidth(), getHeight());
}
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入java.util.Random;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类游戏扩展JPanel{
公共静态void main(字符串[]args){
javax.swing.SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
start();
}
});
}
静态void start(){
JFrame=新JFrame(“游戏”);
JPanel newFrame=newmaingamescreen();
frame.getContentPane().add(newFrame);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
}
类MainGameScreen扩展了JPanel{
公共主屏幕(){
setPreferredSize(新尺寸(864551));
setLayout(新的GridBagLayout());
挫折背景(颜色:绿色);
GridBagConstraints gbc=新的GridBagConstraints();
gbc.fill=GridBagConstraints.BOTH;
gbc.weightx=1;
gbc.weighty=1;
gbc.ipadx=0;//更改为64以查看不需要的效果
gbc.ipady=0//^
对于(int i=0;i我将使用网格布局作为带有方形瓷砖的面板,并将其嵌套在窗口其余部分的另一个布局(GridBagLayout、BorderLayout、BoxLayout或一些布局组合)中
也就是说,在这种情况下,GridLayout和GridBagLayout都会均匀地分布像素。由于您只能使用整个像素,因此在分割空间后会留下一个余数,这将用作填充。这在很大程度上是不可避免的,尽管有一些潜在的解决方法:
- 强制执行某些窗口大小
- 绘制比需要大的面板,但使用视口,以便在视图中截断多余的平铺
- 添加与平铺区域相邻的其他元素,以有效隐藏存在额外填充的事实
如果您对第一个选项没有意见,可以稍作修改,将窗口捕捉到一个兼容的大小,这样就没有余数了(注意:我还将几个硬编码的int改为常量):
package com.example.game;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入java.awt.event.ComponentAdapter;
导入java.awt.event.ComponentEvent;
导入java.util.Random;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类游戏扩展了JPanel{
公共静态void main(字符串[]args){
javax.swing.SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
start();
}
});
}
静态void start(){
最终JFrame=新JFrame(“游戏”);
JPanel newFrame=newmaingamescreen();
frame.addComponentListener(新的ComponentAdapter(){
@凌驾
公共无效组件已恢复(组件事件e){
int h=frame.getContentPane().getHeight()%MainGameScreen.ROWS;
int w=frame.getContentPane().getWidth()%MainGameScreen.COLS;
//从大小中减去剩余像素。
frame.setSize(frame.getWidth()-w,frame.getHeight()-h);
}
});
frame.getContentPane().add(newFrame);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
}
类MainGameScreen扩展了JPanel{
静态最终整数行=13;
静态最终整数=27;
公共主屏幕(){
setPreferredSize(新尺寸(864551));
setLayout(新的GridBagLayout());
挫折背景(颜色:绿色);
GridBagConstraints gbc=新的GridBagConstraints();
gbc.fill=GridBagConstraints.BOTH;
gbc.weightx=1;
gbc.weighty=1;
gbc.ipadx=0;//更改为64以查看不需要的效果
gbc.ipady=0//^
对于(int i=0;与主题无关,但我建议不要使用GridBagLayout
,除非您必须这样做。这只是一个令人头痛的问题-大多数相同的功能都可以通过BoxLayout
实现。因为每个磁贴都与其他磁贴具有完全相同的权重,并且像素不能是c
package com.example.game;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JPanel {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
}
});
}
static void start() {
final JFrame frame = new JFrame("Game");
JPanel newFrame = new MainGameScreen();
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
int h = frame.getContentPane().getHeight() % MainGameScreen.ROWS;
int w = frame.getContentPane().getWidth() % MainGameScreen.COLS;
// Subtract the remainder pixels from the size.
frame.setSize(frame.getWidth() - w, frame.getHeight() - h);
}
});
frame.getContentPane().add(newFrame);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MainGameScreen extends JPanel {
static final int ROWS = 13;
static final int COLS = 27;
public MainGameScreen() {
setPreferredSize(new Dimension(864, 551));
setLayout(new GridBagLayout());
setBackground(Color.green);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.ipadx = 0; //Change to 64 to see undesired effects
gbc.ipady = 0; //^
for (int i=0;i<ROWS;i++) {
for (int j=0;j<COLS;j++) {
gbc.gridx = j;
gbc.gridy = i;
add(new ImagePanel(), gbc);
}
}
}
}
class ImagePanel extends JComponent {
private int r,g,b;
public ImagePanel() {
Random generator = new Random();
r = generator.nextInt(100)+1;
g = generator.nextInt(100)+1;
b = generator.nextInt(100)+1;
}
@Override
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
gr.setColor(new Color(r,g,b));
gr.fillRect(0, 0, getWidth(), getHeight());
}
}