Class 扩展 JLabel 不遵循容器的布局

Class extending JLabel doesn't follow the layout of the container

我正在尝试使用 WindowBuilder 在 Eclipse 中创建一个数独应用程序。我决定使用 JLabel 作为单元格。我有一个扩展 JLabel 并添加 3 个字段的 class 单元格 - 值、x 和 y。 Cells 位于 9 个 JPanels 中,带有 GridLayout。

问题是,当我将单元格添加到 JPanel 中时,它们看起来像是彼此堆叠在一起,就好像 GridLayout 不起作用一样。当我用 JLabels 做同样的事情时,它们看起来很好。

有细胞:

使用 JLabel:

这是单元格 class:

import javax.swing.JLabel;

public class Cell extends JLabel {


private static final long serialVersionUID = 1L;
private int value;
private int x;
private int y;

public Cell(int value, int x, int y) {
    super(Integer.toString(value));
    this.value = value;
    this.x = x;
    this.y = y;
}

public Cell(int value) {
    this.value = value;
}

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}

public int getX() {
    return x;
}

public void setX(int x) {
    this.x = x;
}

public int getY() {
    return y;
}

public void setY(int y) {
    this.y = y;
}

}

下面是 MainFrame class。我正在更改 initialize() 方法中的两行。它适用于

JLabel cell = new JLabel(Integer.toString(j));

但没有

JLabel cell = new Cell(j, j, i);

完整的 MainFrame class:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;


public class MainFrame {

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainFrame window = new MainFrame();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public MainFrame() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setResizable(false);
    frame.setBounds(100, 100, 458, 532);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new GridLayout(1, 0, 0, 0));

    JPanel mainPanel = new JPanel();
    mainPanel.setForeground(Color.WHITE);
    mainPanel.setBorder(new LineBorder(new Color(0, 0, 0), 2));
    mainPanel.setBounds(10, 61, 422, 422);
    frame.getContentPane().add(mainPanel);
    mainPanel.setLayout(new GridLayout(3, 0, 0, 0));

    JPanel[] bigSquares = new JPanel[9];

    for (int i=0; i < 9; i++) {

        bigSquares[i] = new JPanel();
        mainPanel.add(bigSquares[i]);
        bigSquares[i].setBorder(new LineBorder(new Color(0, 0, 0), 2));
        bigSquares[i].setLayout(new GridLayout(3, 0, 0, 0));


        for (int j=0; j < 9; j++) {

            JLabel cell = new Cell(j, j, i);
            //JLabel cell = new JLabel();

            cell.setBorder(new LineBorder(new Color(0, 0, 0), 1));
            cell.setVerticalAlignment(SwingConstants.CENTER);
            cell.setHorizontalAlignment(SwingConstants.CENTER);
            cell.setFont(new Font("Tahoma", Font.PLAIN, 14));

            bigSquares[i].add(cell);
        }
    }


}
}

问题是 JLabel 已经有 getX()getY() 方法(实际上,这些方法来自 JComponent。请参阅 JavaDoc for getX()

原始方法

Returns the current x/y coordinate of the component's origin

通过覆盖 getXgetY,您实际上是在定义组件相对于其父容器的坐标。


一种解决方案是将您的方法重命名为 getCellXgetCellY.

另一种解决方案是使用单独的 class Cell,它有一个值、坐标 x、y 和一个用于显示该值的 JLabel。