尝试在另一个线程中打开JFrame时,java.lang.ExceptionInInitializerError错误的原因和解决方法是什么?

时间:2011-01-08 00:57:01

标签: java swing jframe

我正在尝试创建一个测试类来打开JFrame。为了阻止窗口关闭主线程结束的那一刻,我添加了代码以打开另一个线程中的窗口。每次运行应用程序时,我都会遇到以下异常:

Exception in thread "Test Thread" java.lang.ExceptionInInitializerError
    at java.lang.Runtime.addShutdownHook(Runtime.java:192)
    at java.util.logging.LogManager.(LogManager.java:237)
    at java.util.logging.LogManager$1.run(LogManager.java:177)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.util.logging.LogManager.(LogManager.java:158)
    at java.util.logging.Logger.getLogger(Logger.java:273)
    at java.awt.Component.(Component.java:173)
    at reflector.ApplicationRunner.startObjectsPool(ApplicationRunner.java:18)
    at reflector.ReflectorEndToEndTest$1.run(ReflectorEndToEndTest.java:20)
Caused by: java.lang.IllegalStateException: Shutdown in progress
    at java.lang.Shutdown.add(Shutdown.java:62)
    at java.lang.ApplicationShutdownHooks.(ApplicationShutdownHooks.java:21)
... 9 more

代码如下:

@Test
public void createIntegerClass() throws Exception {
    Thread t = new Thread("Test Thread") {
        @Override
        public void run() {
            try {
                application.startObjectsPool();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    t.start();
    t.setDaemon(true);
}

public class ApplicationRunner {

    public final static String[] NO_ARGS = null;

    public void startObjectsPool() throws Exception {

        ObjectsPoolFrame frame = new ObjectsPoolFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

public ObjectsPoolFrame() {
    setTitle("Objects Pool");

    // get screen dimension
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenHeight = screenSize.height;
    int screenWidth = screenSize.width;

    // center frame in screen
    setSize(screenWidth / 2, screenHeight / 2);
    setLocation(screenWidth / 4, screenHeight / 4);

    op = new ObjectPool();

    // add buttons on the top
    j1 = new JButton("Create Object");
    j2 = new JButton("Delete Object");
    j3 = new JButton("Display Methods");
    j4 = new JButton("Invoke Method");
    JPanel buttonPanel = new JPanel();
    buttonPanel.add(j1);
    buttonPanel.add(j2);
    buttonPanel.add(j3);
    buttonPanel.add(j4);
    add(buttonPanel, BorderLayout.NORTH);
    j1.addActionListener(new CreateObjectAction());
    j2.addActionListener(new DeleteObjectAction());
    j3.addActionListener(new DisplayMethodAction());
    j4.addActionListener(new InvokeMethodAction());

    comboBox = new JComboBox();
    comboBox.addActionListener(new ComboBoxClearAction());
    addComboBoxItem();

    comboBox2 = new JComboBox();

    JPanel comboPanel = new JPanel();
    comboPanel.add(new JLabel("Objects"));
    comboPanel.add(comboBox);

    comboPanel.add(new JLabel("Methods"));
    comboPanel.add(comboBox2);
    add(comboPanel, BorderLayout.CENTER);

    displayMessage = new JLabel();
    JPanel displayPanel = new JPanel();
    displayPanel.add(displayMessage);
    add(displayPanel, BorderLayout.SOUTH);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

我无法理解为什么我会遇到这个问题。

2 个答案:

答案 0 :(得分:1)

异常消息告诉您确切的错误:您正在尝试在JVM关闭时创建新线程。

主线程完成时JVM关闭的原因是您在事件线程上调用setDaemon(true)。删除该行,只要该线程处于活动状态,JVM就会保持不变。

答案 1 :(得分:0)

当您尝试将线程设置为守护程序(true)时,会出现问题。当您退出应用程序时,线程无法停止,因此会抛出java.lang.IllegalStateException: Shutdown in progress

当你遇到这个问题时,你必须明确地告诉运行时无论如何都要通过添加一个击落挂钩来关闭线程。

public void createIntegerClass() throws Exception {
    Thread t = new Thread("Test Thread") {...};

    Runtime.getRuntime().addShutdownHook(t);//explicit!
    t.start();
    t.setDaemon(true);
}