在 Swing 中使用空布局时,直到我将鼠标悬停在它们上面时,我的组件才会出现

When using null layout in Swing, my components don't appear until I hover on them

最近我在 Java 中开始使用 Swing 制作一些简单的游戏。我目前的项目是一个类似国际象棋的游戏,所以我想我会先用 JButtons 制作一个 8 x 8 的网格,然后从那里开始。

问题是每次我 运行 我的应用程序时,一半的按钮都不见了,只有当我将鼠标悬停在它们上方时它们才会出现。根据我对这个问题的搜索,大多数建议都是说我不应该使用 null 布局,我应该使用一些已经在 Swing 中的布局。但据我目前所见,Swing 布局使用起来很痛苦(至少与 Android 布局相比),我现在宁愿只使用绝对定位。

我还发现添加 panel.repaint();修复了丢失的按钮,但我不喜欢该解决方案,因为它并没有真正解决问题,但更像是修补它。当 运行我的应用重绘时,我仍然会在一瞬间看到丢失的按钮,直到它们被重绘。

所以我正在寻找的是为什么首先会发生这种情况,有什么办法可以在不使用糟糕的 Swing 布局的情况下不发生这种情况。

import javax.swing.*;

public class Main {

    static final int TILE = 70;
    static final int WIDTH = 600;
    static final int HEIGHT = 600;

    public static void main(String[] args){
        JFrame frame = new JFrame("Knight's tour");
        frame.setSize(WIDTH, HEIGHT);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        JPanel panel = new JPanel();
        panel.setLayout(null);
        frame.add(panel);

        JButton[][] tiles = new JButton[8][8];

        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                tiles[i][j] = new JButton();
                tiles[i][j].setLocation(i*TILE, j*TILE);
                tiles[i][j].setSize(TILE, TILE);
                panel.add(tiles[i][j]);
            }
        }

        //panel.repaint(); //this thing fixes it, but I am looking for a better fix
    }
}

出于多种原因避免使用空布局。不同的平台会以不同的方式对待它们。它们难以维护,还有许多其他原因。而是使用布局管理器,让它们进行组件的布局和大小调整,就像它们设计用于 Swing 应用程序一样。在 Laying out components Within a Container

了解更多信息

对于国际象棋游戏,听起来 GridLayout 非常适合您正在寻找的东西,而且不会出现您当前遇到的相同问题。

通常在添加面板及其组件后 last:

frame.pack();
frame.setVisible(true);

pack() 根据首选尺寸进行一些布局。

也可以做一个 JTable 8x8。

首先,您需要在事件线程上进行绘制。 其次,您应该制作一个扩展 JPanel 的 class,如果您真的想使用空布局,您的面板应该覆盖 paintComponent,并且该方法应该首先调用 super.paintComponent() 然后定位子组件适当的按钮。