java - 组件的奇怪问题

标签 java swing jpanel

我正在我的 Java 类上开发一个应用程序,但遇到了一个奇怪的问题。我需要在网格中表示数据,因此使用 GridLayout 是一个明显的选择,但这里有一个问题。 我一直得到几乎空的框架(注意左上角的小白色矩形)。

issue

这是产生此结果的代码片段

//not important class code 
public static void main(String args[]) {    
    JFrame frame = new JFrame("Wolves & Rabbits");
    frame.setSize(640, 480);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //want to create a 12x9 grid with 2 black and 4 pink rectangles
    Board board = new Board(12, 9, 2, 4, 1000);

    frame.add(board);

    frame.setResizable(false);
    frame.setVisible(true);
}

//Board.java (Board class) extends JPanel
public JPanel fields[][];
private Integer boardWidth, boardHeight;
private ArrayList<AnimalThread> animals;
private Integer wolvesCount, rabbitsCount;

public Board(int w, int h) {
    super(new GridLayout(h, w, 4, 4));

    fields = new JPanel[w][h];
    boardWidth = new Integer(w);
    boardHeight = new Integer(h);
    animals = null;
    wolvesCount = new Integer(0);
    rabbitsCount = new Integer(0);

    //creating white rectangles
    for (int i = 0; i < boardHeight; i++)
        for (int j = 0; j < boardWidth; j++) {
            fields[j][i] = new JPanel(true);
            fields[j][i].setBackground(AnimalThread.NONE);
            this.add(fields[j][i]);
        }

    AnimalThread.setLinkToBoard(this);
}

public Board(int w, int h, int wolves, int rabbits, int k) {
    this(w, h);

    animals = new ArrayList<AnimalThread>();

    while (boardWidth*boardHeight < 2*wolves*rabbits) {
        wolves--;
        rabbits--;
    }       
    wolvesCount = wolves;
    rabbitsCount = rabbits;

    WolfThread.setRabbitsCount(rabbitsCount);

    //randomly place colored rectangles
    this.randomize(wolves, rabbits, k);     
}

奇怪的是,根本不更改 Board 类,并且只需对 main 方法进行一些更改,我就能够显示正确的网格。

issue resolved

在本例中主要方法是

//not important class code
public static void main(String args[]) {    
    JFrame frame = new JFrame("Wolves & Rabbits");
    frame.setSize(640, 480);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Board board = new Board(12, 9, 2, 4, 1000);

    //THE CHANGE!
    JPanel panel = new JPanel(new GridLayout(12, 9, 4, 4));
    for (int i = 0; i < 9; i++)
        for (int j = 0; j < 12; j++) {
            JPanel tmp = board.fields[j][i];
            panel.add(tmp);
        }
    frame.add(panel);

    frame.setResizable(false);
    frame.setVisible(true);
}

有人知道是什么导致了这个令人恼火的问题吗?任何线索将不胜感激。

最佳答案

当您使用 Swing 时,您必须在 EDT 上执行 Swing UI 代码。所以至少你的主要方法应该是这样的:

public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("Wolves & Rabbits");
            frame.setSize(640, 480);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // want to create a 12x9 grid with 2 black and 4 pink rectangles
            Board board = new Board(12, 9, 2, 4, 1000);

            frame.add(board);

            frame.setResizable(false);
            frame.setVisible(true);
        }
    });
}

从其他线程访问 Swing 对象的变量然后 EDT 将导致问题。其中许多问题是间歇性的并且难以追踪(就像大多数并发问题一样)。

“AnimalThread”对象的名称似乎暗示它是一个线程。您不能(实际上您可以,正如您所演示的那样:-)直接操作“存在”在 EDT 上的 Swing 对象。如果另一个线程想要更​​改 EDT 上的某些内容,则需要使用“SwingUtilities.invokeLater”或“SwingUtilities.invokeAndWait”方法。

关于java - 组件的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13787558/

相关文章:

java 注释 - 库或语言功能?

java - 单击鼠标时更改值

java - 文本重复

java - 将 JInternalFrame 置于其他 JPanel 之上

java - 在 spring 中加入而不映射实体

java - 从字符串中删除 "empty"字符

java - 从xls/xlsx文档中读取,哪个API? java

java - 使用循环将数据库中的值添加到 List<String> Array.asList

java - 屏幕和警棍的分割 Pane

java,组件仅在直接添加到框架时显示