[英]GridBagLayout stacks labels when using custom subclass from Jlabel
I am writing a GUI with Swing. 我正在用Swing编写GUI。 I'm using a
GridBagLayout
to display multiple JLabels
in a grid (basically like a chess board). 我正在使用
GridBagLayout
在网格中显示多个JLabels
(基本上像棋盘一样)。 As soon as I use a self made label class derived from JLabel
instead of JLabel
, the GridBagLayout
stacks every label on the top left corner of the JPanel
. 一旦我使用从
JLabel
而不是JLabel
派生的自制标签类, GridBagLayout
所有标签堆叠在JPanel
左上角。
Either my subclass TileLabel
is incorrect or I don't use the layout and constraints the right way. 我的子类
TileLabel
不正确,或者我没有使用正确的布局和约束。 I think the last one because I can't see what would be a problem in such a minimal subclass. 我认为是最后一个,因为我看不到最小的子类会有什么问题。
This is how it looks using JLabel
(L represents a label): 这是使用
JLabel
外观(L表示标签):
(MenuBar)
L L L L L L L L L
L L L L L L L L L
L L L L L L L L L
This is how it looks using TileLabel
(S represents all the labels stacked): 使用
TileLabel
外观TileLabel
(S代表堆叠的所有标签):
(MenuBar)
S
This is my simple subclass from JLabel: 这是我来自JLabel的简单子类:
import javax.swing.JLabel;
public class TileLabel extends JLabel {
private static final long serialVersionUID = 6718776819945522562L;
private int x;
private int y;
public TileLabel(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
And this is the GUI class. 这是GUI类。 I Marked the three lines where I used my custom label which lead to the layout problem.
我标记了三行使用自定义标签的行,这导致布局问题。
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainGUI extends JPanel {
private static final long serialVersionUID = -8750891542665009043L;
private JFrame frame;
private MainMenuBar menuBar;
private TileLabel[][] labelGrid; // <-- LINE 1
private GridBagConstraints constraints;
private int gridWidth;
private int gridHeight;
// Basic constructor.
public MainGUI(int frameWidth, int frameHeight) {
super(new GridBagLayout());
constraints = new GridBagConstraints();
buildFrame(frameWidth, frameHeight);
buildLabelGrid(frameWidth, frameHeight);
}
// Builds the frame.
private void buildFrame(int frameWidth, int frameHeight) {
menuBar = new MainMenuBar();
frame = new JFrame("Carcasonne");
frame.getContentPane().add(this);
frame.setJMenuBar(menuBar);
frame.setResizable(false);
frame.setVisible(true);
frame.setSize(frameWidth, frameHeight);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(new Color(165, 200, 245));
}
// Creates the grid of labels.
private void buildLabelGrid(int frameWidth, int frameHeight) {
gridWidth = frameWidth / 100;
gridHeight = frameHeight / 100;
labelGrid = new TileLabel[gridWidth][gridHeight]; // <-- LINE 2
for (int x = 0; x < gridWidth; x++) {
for (int y = 0; y < gridHeight; y++) {
labelGrid[x][y] = new TileLabel(x, y); // <-- LINE 3
constraints.gridx = x;
constraints.gridy = y;
add(labelGrid[x][y], constraints); // add label with constraints
}
}
}
// sets the icon of a specific label
public void paint(Tile tile, int x, int y) {
if (x >= 0 && x < gridWidth && y >= 0 && y < gridHeight) {
labelGrid[x][y].setIcon(tile.getImage());
} else {
throw new IllegalArgumentException("Invalid label grid position (" + x + ", " + y + ")");
}
}
// Just to test this GUI:
public static void main(String[] args) {
MainGUI gui = new MainGUI(1280, 768);
Tile tile = TileFactory.createTile(TileType.Road);
for (int x = 0; x < 12; x++) {
for (int y = 0; y < 7; y++) {
gui.paint(tile, x, x);
}
}
}
}
Where is the problem? 问题出在哪儿?
There are quite a few things to fix in your code, but your problem originates from 3 things: 您的代码中有很多要解决的问题,但是您的问题源自三件事:
Your method definitions in your custom label: 您的自定义标签中的方法定义:
public class TileLabel extends JLabel { // @Override !!!! public int getX() { return x; } // @Override !!!! public int getY() { return y; } }
You are overriding JComponent
's getX()
and getY()
, which are responsible for returning their coordinates. 您将重写
JComponent
的getX()
和getY()
,它们负责返回它们的坐标。 This messes up the layout completely. 这完全弄乱了布局。
Be careful with your paint
method, a method with the same name exists in a superclass, though you are saved in this case since the arguments are different. 请注意您的
paint
方法,在同一个类中存在一个具有相同名称的方法,尽管在这种情况下您会被保存,因为参数是不同的。
You have a typo at your loop: gui.paint(tile, x, x)
should be gui.paint(tile, x, y)
. 您在循环中
gui.paint(tile, x, x)
错别字: gui.paint(tile, x, x)
应该是gui.paint(tile, x, y)
。
The order in which you call your methods is wrong. 您调用方法的顺序是错误的。 First, you create the frame and display it, then you change its contents by adding the panel with the labels to it, then you change the text in the labels.
首先,创建框架并显示它,然后通过添加带有标签的面板来更改其内容,然后更改标签中的文本。 You should do this the other way around.
您应该以其他方式执行此操作。
My recommendations: 我的建议:
paint
method be made a member of your TileLabel
class. paint
方法成为TileLabel
类的成员。 It makes more sense. pack()
for the frame to calculate the correct size. pack()
来计算正确的大小。 You have accidentally overridden JComponent#getX()
and JComponent#getY()
. 您不小心覆盖了
JComponent#getX()
和JComponent#getY()
。 The values returned by this method are not consistent with the values that the layout may set internally (via calls to setBounds
or so). 此方法返回的值是不与该布局可以内部设置(通过调用的值一致
setBounds
左右)。 This messes up the layout. 这弄乱了布局。
(Admittedly, I did not really check whether this is the reason, but it likely is, and it is a problem in general!) (诚然,我并没有真正检查这是否是原因,但很可能是这样,而且通常是个问题!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.