在 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() 然后定位子组件适当的按钮。
最近我在 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() 然后定位子组件适当的按钮。