[英]GridBagLayout stacks labels when using custom subclass from Jlabel
我正在用Swing編寫GUI。 我正在使用GridBagLayout
在網格中顯示多個JLabels
(基本上像棋盤一樣)。 一旦我使用從JLabel
而不是JLabel
派生的自制標簽類, GridBagLayout
所有標簽堆疊在JPanel
左上角。
我的子類TileLabel
不正確,或者我沒有使用正確的布局和約束。 我認為是最后一個,因為我看不到最小的子類會有什么問題。
這是使用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
使用TileLabel
外觀TileLabel
(S代表堆疊的所有標簽):
(MenuBar)
S
這是我來自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;
}
}
這是GUI類。 我標記了三行使用自定義標簽的行,這導致布局問題。
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);
}
}
}
}
問題出在哪兒?
您的代碼中有很多要解決的問題,但是您的問題源自三件事:
您的自定義標簽中的方法定義:
public class TileLabel extends JLabel { // @Override !!!! public int getX() { return x; } // @Override !!!! public int getY() { return y; } }
您將重寫JComponent
的getX()
和getY()
,它們負責返回它們的坐標。 這完全弄亂了布局。
請注意您的paint
方法,在同一個類中存在一個具有相同名稱的方法,盡管在這種情況下您會被保存,因為參數是不同的。
您在循環中gui.paint(tile, x, x)
錯別字: gui.paint(tile, x, x)
應該是gui.paint(tile, x, y)
。
您調用方法的順序是錯誤的。 首先,創建框架並顯示它,然后通過添加帶有標簽的面板來更改其內容,然后更改標簽中的文本。 您應該以其他方式執行此操作。
我的建議:
paint
方法成為TileLabel
類的成員。 這更有意義。 pack()
來計算正確的大小。 您不小心覆蓋了JComponent#getX()
和JComponent#getY()
。 此方法返回的值是不與該布局可以內部設置(通過調用的值一致setBounds
左右)。 這弄亂了布局。
(誠然,我並沒有真正檢查這是否是原因,但很可能是這樣,而且通常是個問題!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.