Java Swing:NullPointerException在自己创建的可调整大小的GUI中

Java Swing:NullPointerException在自己创建的可调整大小的GUI中,java,swing,nullpointerexception,Java,Swing,Nullpointerexception,首先,我知道使用setLayout(null)不是最好的方法,但该程序的目标是尝试编写一个自己可以调整大小的GUI 首先,这三个类(拆分GroundFrame.java和HomeScreen.java的原因是将来会有多个窗口): Start.java public class Start { public static void main(String[] arg){ new GroundFrame(); } } public class GroundFr

首先,我知道使用
setLayout(null)
不是最好的方法,但该程序的目标是尝试编写一个自己可以调整大小的GUI

首先,这三个类(拆分
GroundFrame.java
HomeScreen.java
的原因是将来会有多个窗口):

Start.java

public class Start {

    public static void main(String[] arg){
        new GroundFrame();  
    }
}
public class GroundFrame extends JFrame{

    static final long       serialVersionUID = 0;
    Container               contentPane;
    HomeScreen              homeScreen;

    public GroundFrame(){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private void createAndShowGUI(){
        createBasicFrame();
        createPaneAndAddHome();
        setVisible(true);
    }

    private void createBasicFrame(){
        addComponentListener(new ComponentListener() {
            public void componentShown(ComponentEvent e) {}
            public void componentResized(ComponentEvent e) {
                homeScreen.resizeHome(getContentPane().getSize());
            }
            public void componentMoved(ComponentEvent e) {}
            public void componentHidden(ComponentEvent e) {}
        });

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = getContentPane();
        contentPane.setPreferredSize(new Dimension(600, 400));
        contentPane.setLayout(null);
        pack();
    }

    private void createPaneAndAddHome(){
        homeScreen = new HomeScreen(contentPane.getSize());
        contentPane.add(homeScreen);
    }
}
public class HomeScreen extends JPanel{

    static final long       serialVersionUID = 0;
    private JLabel          labelHeader, labelFooter;
    private JTextField      textField;
    private int             x, y;

    public HomeScreen(final Dimension dimension){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowPanel(dimension);
            }
        });
    }

    private void createAndShowPanel(Dimension dimension){
        labelHeader = new JLabel("HEADER");
        textField = new JTextField();
        labelFooter = new JLabel("FOOTER");
        setupPanel(dimension);
    }

    private void setupPanel(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        setBounds(0,0,x,y);
        setLayout(null);
        setupTitle(new Dimension(x,y));
    }

    private void setupTitle(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        labelHeader.setBounds((int)(x*0.1), (int)(y*0.1), (int)(x*0.8), (int)(y*0.3));
        labelHeader.setOpaque(true);
        labelHeader.setBackground(Color.cyan);
        labelHeader.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        textField.setBounds((int)(x*0.25), (int)(y*0.45), (int)(x*0.5), (int)(y*0.1));
        textField.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.08)));

        labelFooter.setBounds((int)(x*0.1), (int)(y*0.6), (int)(x*0.8), (int)(y*0.3));
        labelFooter.setOpaque(true);
        labelFooter.setBackground(Color.cyan);
        labelFooter.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        add(labelHeader);
        add(labelFooter);
        add(textField);
    }

    public void resizeHome(Dimension dimension){
        setupPanel(dimension);
    }
}
GroundFrame.java

public class Start {

    public static void main(String[] arg){
        new GroundFrame();  
    }
}
public class GroundFrame extends JFrame{

    static final long       serialVersionUID = 0;
    Container               contentPane;
    HomeScreen              homeScreen;

    public GroundFrame(){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private void createAndShowGUI(){
        createBasicFrame();
        createPaneAndAddHome();
        setVisible(true);
    }

    private void createBasicFrame(){
        addComponentListener(new ComponentListener() {
            public void componentShown(ComponentEvent e) {}
            public void componentResized(ComponentEvent e) {
                homeScreen.resizeHome(getContentPane().getSize());
            }
            public void componentMoved(ComponentEvent e) {}
            public void componentHidden(ComponentEvent e) {}
        });

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = getContentPane();
        contentPane.setPreferredSize(new Dimension(600, 400));
        contentPane.setLayout(null);
        pack();
    }

    private void createPaneAndAddHome(){
        homeScreen = new HomeScreen(contentPane.getSize());
        contentPane.add(homeScreen);
    }
}
public class HomeScreen extends JPanel{

    static final long       serialVersionUID = 0;
    private JLabel          labelHeader, labelFooter;
    private JTextField      textField;
    private int             x, y;

    public HomeScreen(final Dimension dimension){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowPanel(dimension);
            }
        });
    }

    private void createAndShowPanel(Dimension dimension){
        labelHeader = new JLabel("HEADER");
        textField = new JTextField();
        labelFooter = new JLabel("FOOTER");
        setupPanel(dimension);
    }

    private void setupPanel(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        setBounds(0,0,x,y);
        setLayout(null);
        setupTitle(new Dimension(x,y));
    }

    private void setupTitle(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        labelHeader.setBounds((int)(x*0.1), (int)(y*0.1), (int)(x*0.8), (int)(y*0.3));
        labelHeader.setOpaque(true);
        labelHeader.setBackground(Color.cyan);
        labelHeader.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        textField.setBounds((int)(x*0.25), (int)(y*0.45), (int)(x*0.5), (int)(y*0.1));
        textField.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.08)));

        labelFooter.setBounds((int)(x*0.1), (int)(y*0.6), (int)(x*0.8), (int)(y*0.3));
        labelFooter.setOpaque(true);
        labelFooter.setBackground(Color.cyan);
        labelFooter.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        add(labelHeader);
        add(labelFooter);
        add(textField);
    }

    public void resizeHome(Dimension dimension){
        setupPanel(dimension);
    }
}
HomeScreen.java

public class Start {

    public static void main(String[] arg){
        new GroundFrame();  
    }
}
public class GroundFrame extends JFrame{

    static final long       serialVersionUID = 0;
    Container               contentPane;
    HomeScreen              homeScreen;

    public GroundFrame(){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private void createAndShowGUI(){
        createBasicFrame();
        createPaneAndAddHome();
        setVisible(true);
    }

    private void createBasicFrame(){
        addComponentListener(new ComponentListener() {
            public void componentShown(ComponentEvent e) {}
            public void componentResized(ComponentEvent e) {
                homeScreen.resizeHome(getContentPane().getSize());
            }
            public void componentMoved(ComponentEvent e) {}
            public void componentHidden(ComponentEvent e) {}
        });

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = getContentPane();
        contentPane.setPreferredSize(new Dimension(600, 400));
        contentPane.setLayout(null);
        pack();
    }

    private void createPaneAndAddHome(){
        homeScreen = new HomeScreen(contentPane.getSize());
        contentPane.add(homeScreen);
    }
}
public class HomeScreen extends JPanel{

    static final long       serialVersionUID = 0;
    private JLabel          labelHeader, labelFooter;
    private JTextField      textField;
    private int             x, y;

    public HomeScreen(final Dimension dimension){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowPanel(dimension);
            }
        });
    }

    private void createAndShowPanel(Dimension dimension){
        labelHeader = new JLabel("HEADER");
        textField = new JTextField();
        labelFooter = new JLabel("FOOTER");
        setupPanel(dimension);
    }

    private void setupPanel(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        setBounds(0,0,x,y);
        setLayout(null);
        setupTitle(new Dimension(x,y));
    }

    private void setupTitle(Dimension dimension){
        x = dimension.width;
        y = dimension.height;
        labelHeader.setBounds((int)(x*0.1), (int)(y*0.1), (int)(x*0.8), (int)(y*0.3));
        labelHeader.setOpaque(true);
        labelHeader.setBackground(Color.cyan);
        labelHeader.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        textField.setBounds((int)(x*0.25), (int)(y*0.45), (int)(x*0.5), (int)(y*0.1));
        textField.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.08)));

        labelFooter.setBounds((int)(x*0.1), (int)(y*0.6), (int)(x*0.8), (int)(y*0.3));
        labelFooter.setOpaque(true);
        labelFooter.setBackground(Color.cyan);
        labelFooter.setFont(new Font("Arial", Font.PLAIN, (int)(y*0.25)));

        add(labelHeader);
        add(labelFooter);
        add(textField);
    }

    public void resizeHome(Dimension dimension){
        setupPanel(dimension);
    }
}
现在一切都按照我的想法运行,但在
HomeScreen.java

labelHeader.setBounds((int)(x*0.1), (int)(y*0.1), (int)(x*0.8), (int)(y*0.3));
这是错误消息

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at gui.HomeScreen.setupTitle(HomeScreen.java:45)
    at gui.HomeScreen.setupPanel(HomeScreen.java:39)
    at gui.HomeScreen.resizeHome(HomeScreen.java:64)
    at gui.GroundFrame$2.componentResized(GroundFrame.java:43)
    at java.awt.AWTEventMulticaster.componentResized(AWTEventMulticaster.java:159)
    at java.awt.Component.processComponentEvent(Component.java:6331)
    at java.awt.Component.processEvent(Component.java:6285)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Window.processEvent(Window.java:2022)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:703)
    at java.awt.EventQueue.access$000(EventQueue.java:102)
    at java.awt.EventQueue$3.run(EventQueue.java:662)
    at java.awt.EventQueue$3.run(EventQueue.java:660)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:676)
    at java.awt.EventQueue$4.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:673)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

尽管如此,该程序仍在继续运行,因为什么都没有发生。毕竟,该错误在程序启动时出现,因此在不执行手动调整大小的点(错误消息指示从
主屏幕
s
resizeHome()
调用该错误)。为什么会这样?为什么程序继续运行?GUI本身的构建是否可能是
ComponentListener
s
componentResistized()

这是因为您在构造函数中使用了
SwingUtilities\invokeLater

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});
您所创建的是UI中的竞争条件

基本上,
homeScreen.resizeHome
在调用
homeScreen\createAndShowPanel
之前被调用(从
ComponentResistized
),这意味着
LabelHeader
尚未初始化

您当前的事件顺序看起来像

  • 主要
  • newgrounframe()
  • invokeLater
    GroundFrame#createAndShowGUI
  • 。。。(返回主控室)
  • GroundFrame#createBasicFrame
    (添加
    ComponentListener
    pack
  • GroundFrame#CreatePaneandHome
  • 新主屏幕
  • invokeLater
    主屏幕#createAndShowPanel
    。。。立即返回
  • GrounFrame#设置可见(true)
  • GrounFrame#ComponentListener#componentresisted
  • 主屏幕#调整主页大小
  • 主屏幕#设置面板
  • 空指针异常
  • 主屏幕#创建和显示面板
您应该在
main

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new GroundFrame();
        }
    });
}
并删除对
SwingUtilities#invokeLater