简体   繁体   English

在Swing中使用null布局时,直到将鼠标悬停在它们上时,我的组件才会显示

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

Recently I've been getting into making some simple games with Swing in Java. 最近,我开始使用Java中的Swing制作一些简单的游戏。 My current project is a chess-like game, so I figured I would start by making an 8 by 8 grid with JButtons and go from there. 我当前的项目是一个类似国际象棋的游戏,所以我认为我将从使用JButtons制作8 x 8网格开始,然后从那里开始。

The problem is that every time I run my app, half of the buttons are just missing, and they only appear when I hover above them. 问题在于,每次我运行应用程序时,都会丢失一半的按钮,并且只有当我将鼠标悬停在它们上方时,它们才会出现。 From what I've searched about this problem, most of the suggestions were saying that I shouldn't use null layout, and I should use some of the layouts already in Swing. 从对这个问题的搜索中,大多数建议都说我不应该使用空布局,而应该使用Swing中已经存在的一些布局。 But from what I've seen so far, Swing layouts are just a pain to work with (at least when compared to the Android ones), and I would prefer just using absolute positioning for now. 但是到目前为止,从我所看到的来看,Swing布局的使用非常痛苦(至少与Android相比),并且我现在更喜欢使用绝对定位。

Also I've found that adding panel.repaint(); 我也发现添加panel.repaint(); fixes the missing buttons, but I don't like that solution since it doesn't really fix the problem but more like it patches it. 修复了缺少的按钮,但是我不喜欢该解决方案,因为它不能真正解决问题,但更像是可以解决问题的方法。 When running my app with repaint, I still see the missing buttons for a split second until they are repainted. 使用重新绘制运行我的应用程序时,我仍然会看到丢失的按钮一秒钟,直到重新绘制它们为止。

So what I am looking for is why this thing happens in the first place, and is there any way for it not to happen without using the bad Swing layouts. 所以我要寻找的是为什么这件事首先发生,并且如果不使用不良的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
    }
}

Avoid using null layouts for a number of reason. 出于多种原因,请避免使用空布局。 Different platform will treat them differently. 不同的平台会区别对待它们。 They are difficult to maintain, among many other reasons. 除其他原因外,它们很难维护。 Instead use layout managers, and let them do the laying out and sizing of the components, as they were designed to do with Swing apps. 而是使用布局管理器,让他们像设计用于Swing应用程序那样对组件进行布局和调整大小。 Learn more at Laying out components Within a Container 布局容器中的组件时了解更多信息

For a chess game, it sounds like a GridLayout would be ideal for what you're looking for, without the same problems you're currently experiencing. 对于国际象棋游戏,听起来GridLayout非常适合您要寻找的东西,而不会遇到您当前遇到的相同问题。

Normally one would do last after adding the panel and its components: 通常,在添加面板及其组件之后, 最后要做的是:

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

The pack() doing some layouting on preferred sizes. pack()在首选大小上进行一些布局。

One could do a JTable 8x8 too. 一个人也可以做一个JTable 8x8。

First, you need to do the painting on the event thread. 首先,您需要在事件线程上进行绘制。 Second, you should make a class that extends JPanel, and if you really want to use a null layout, your panel should override paintComponent, and that method should first call super.paintComponent() and then position the child buttons appropriately. 其次,您应该创建一个扩展JPanel的类,如果您确实要使用null布局,则面板应覆盖paintComponent,并且该方法应首先调用super.paintComponent(),然后适当地放置子按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM