java - 在单独的线程中向 JFrame 添加组件

标签 java multithreading swing jframe

我正在编写一个向导,并且想使用方法切换显示的内容。每次运行此代码时,我都会遇到空指针异常。

    public class EventDispatch {

       public static void main(String [] args){
            WizardScreen wiz = new WizardScreen();
            new Thread(wiz).start();
            wiz.welcomeScreen();
       }
    }

    public class WizardScreen implements Runnable{

protected JFrame wizardFrame;
protected JPanel contentPane;
protected JButton newQuote; 
protected JButton openQuote;
protected JLabel title;
GridBagConstraints c;


public WizardScreen(){
    wizardFrame = new JFrame();
    contentPane = new JPanel(new GridBagLayout());
    wizardFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    wizardFrame.setSize(550, 450);
    wizardFrame.setResizable(false);
    wizardFrame.setLocationRelativeTo(null);
    wizardFrame.setTitle("Welcome!");
    wizardFrame.setContentPane(contentPane);
    wizardFrame.setVisible(true);
}

@Override
public void run() {
    System.out.println("Running wizardScreen");

}

public void welcomeScreen(){
    title = new JLabel("Welcome to ExSoft Quote Calculator Alpha 1.0");
    c.gridx = 0;
    c.gridy = 0;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = .5;
    contentPane.add(title, c);
    wizardFrame.validate();
    contentPane.repaint();
}

}

我做错了什么?

最佳答案

浏览一下您的代码...

首先,创建一个用于初始化的 WizardScreen 实例

  • wizardFrame
  • contentPane

其次,启动一个线程...

第三,您在 WizardScreen 实例上调用 welcomeScreen,这会初始化...

  • 标题

然后它尝试访问 cgridx 属性...该属性尚未初始化...

您应该检查 NullPointerException 为您提供的信息...

Exception in thread "main" java.lang.NullPointerException
    at eventdispatch.EventDispatch$WizardScreen.welcomeScreen(EventDispatch.java:52)
    at eventdispatch.EventDispatch.main(EventDispatch.java:20)

它清楚地说明了异常发生的位置,这对您和我们来说都是非常宝贵的信息。

请注意,Swing 不是线程安全的,所有对 UI 的交互和修改都应该在事件调度线程的上下文中发生。请参阅Concurrency in Swing

仅供引用:

通常建议使用 setSizepack,这应该在调用 setVisible 之前最后完成。另请注意,使用 setResizable(false) 会更改窗口的大小...

wizardFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//wizardFrame.setSize(550, 450);
//wizardFrame.setResizable(false);
//wizardFrame.setLocationRelativeTo(null);
wizardFrame.setTitle("Welcome!");
wizardFrame.setContentPane(contentPane);
wizardFrame.setResizable(false);
wizardFrame.pack();
wizardFrame.setLocationRelativeTo(null);
wizardFrame.setVisible(true);

关于java - 在单独的线程中向 JFrame 添加组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22368069/

相关文章:

java - 停止正在运行的线程

Java多线程程序不使用大量CPU

java - 从最后一个 JComboBox 中删除 JComboBox-es 中所选元素的总和

java - 如何使主窗口足够大以显示完整标题

java - 在 Android 上使用哪个 SVM 库?

java - 你使用ant的<depend>任务吗?

java - 我可以在 Java 中为单选按钮设置值吗?

c# - 使用naudio动态播放音频文件

尝试在 netbeans 上运行应用程序时出现 java.lang.NullPointerException 错误

java - invokeAny 是取消线程池中的所有线程还是仅取消可调用线程?