简体   繁体   中英

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. 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.

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. 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.

Also I've found that adding 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.

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. 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.

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.

One could do a JTable 8x8 too.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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