首页 > 解决方案 > 扩展 JLabel 的类不遵循容器的布局

问题描述

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

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

使用细胞:

在此处输入图像描述

使用 JLabels:

在此处输入图像描述

这是 Cell 类:

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 类。我在 initialize() 方法中更改了两行。它适用于

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

但不与

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

完整的 MainFrame 类:

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);
        }
    }


}
}

标签: javaswingjlabellayout-managerwindowbuilder

解决方案


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

原来的方法

返回组件原点的当前 x/y 坐标

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


一种解决方案是将您的方法重命名为getCellX, getCellY

Cell另一种解决方案是使用具有值、坐标 x、y 和用于显示值的 JLabel的单独类。


推荐阅读