Java JButtons don';将鼠标悬停在面板上之前,是否将其加载?

Java JButtons don';将鼠标悬停在面板上之前,是否将其加载?,java,swing,jbutton,layout-manager,null-layout-manager,Java,Swing,Jbutton,Layout Manager,Null Layout Manager,当这是放在一个框架,按钮不加载,直到他们与鼠标悬停,然后他们留在了他们应该。代码如下: 我调用了repaint()和revalidate()之类的函数,但它们似乎都没有解决这个问题。main和Frame是与StartPanel分离的类。谢谢 JButton[][] levels = new JButton[3][8]; public StartPanel(){ setSize(1600, 1000); setLayout(null); int count = 1;

当这是放在一个框架,按钮不加载,直到他们与鼠标悬停,然后他们留在了他们应该。代码如下: 我调用了repaint()和revalidate()之类的函数,但它们似乎都没有解决这个问题。main和Frame是与StartPanel分离的类。谢谢

JButton[][] levels = new JButton[3][8]; 

public StartPanel(){
    setSize(1600, 1000);
    setLayout(null);

    int count = 1;
    int yValue = 150;
    for(int r = 0; r < 3; r++){
        for(int c = 0; c < 8; c++){
            levels[r][c] = new JButton(String.valueOf(count));
            levels[r][c].setLocation(c*190 + 80, yValue);
            levels[r][c].setSize(100, 100);
            this.add(levels[r][c]);
            count++;
        }
        yValue += 200;
    }
}



public static void main(String[] args) {
    Frame f = new Frame();
    StartPanel sp = new StartPanel();
    f.add(sp);
    f.setVisible(true);
}

public Frame() {
    setSize(1600, 1000);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(null);
    setResizable(false);
}
JButton[][]级别=新JButton[3][8];
公共StartPanel(){
设置大小(1600、1000);
setLayout(空);
整数计数=1;
int y值=150;
对于(int r=0;r<3;r++){
对于(int c=0;c<8;c++){
级别[r][c]=新的JButton(String.valueOf(count));
水平[r][c]。设置位置(c*190+80,Y值);
级别[r][c]。设置大小(100100);
本条增补(第[r][c]级);
计数++;
}
Y值+=200;
}
}
公共静态void main(字符串[]args){
帧f=新帧();
StartPanel sp=新的StartPanel();
f、 添加(sp);
f、 setVisible(真);
}
公共框架(){
设置大小(1600、1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(空);
可设置大小(假);
}

避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局管理器一起工作,丢弃这些布局管理器将导致无止境的问题,您将花费越来越多的时间来纠正这些问题

网格布局 我可能建议尝试
GridLayout
,结合类似
EmptyBorder
,您应该能够接近您想要的,例如

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        JButton[][] levels = new JButton[3][8];

        public TestPane() {
            setBorder(new EmptyBorder(40, 40, 40, 40));
            setSize(1600, 1000);
            setLayout(new GridLayout(0, 8, 40, 40));

            int count = 1;
            int yValue = 150;
            for (int r = 0; r < 3; r++) {
                for (int c = 0; c < 8; c++) {
                    levels[r][c] = new JButton(String.valueOf(count));
                    levels[r][c].setMargin(new Insets(50, 50, 50, 50));
                    this.add(levels[r][c]);
                    count++;
                }
                yValue += 200;
            }
        }
    }

}
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        JButton[][] levels = new JButton[3][8];

        public TestPane() {
            setSize(1600, 1000);
            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(25, 25, 25, 25);
            gbc.fill = GridBagConstraints.BOTH;

            int count = 1;
            for (int r = 0; r < 3; r++) {
                gbc.gridx = 0;
                for (int c = 0; c < 8; c++) {
                    levels[r][c] = new JButton(String.valueOf(count));
                    levels[r][c].setMargin(new Insets(50, 50, 50, 50));
                    this.add(levels[r][c], gbc);
                    gbc.gridx++;
                    count++;
                }
                gbc.gridy++;
            }
        }
    }

}


有关更多详细信息,请参见

能否发布一点其余代码?
setLayout(null)EventQueue.invokeLater
。这就是在Swing()中对UI进行更改的方式。不要在线程中更改UI。所有更改都必须在UI线程中进行,这就是这些方法的用途;)@DerekSchuster你是按照我发布的代码运行的还是修改了你现有的代码?@MadProgrammer是的,我找到了。现在它不允许我在面板上使用油漆(图形g)。当我添加该方法时,它会返回到不加载任何按钮的状态。你知道这是为什么吗?