Java Swing应用程序意外终止

我正在尝试用Java编写一个Swing应用程序,它也运行Google AppEngine Dev-Server(参见Developing a Java Application that uses an AppEngine database),并且遇到了Swing Eventloop的一个奇怪问题.

我有以下两个类:

一个调试窗口,它最终会收到日志消息等:

public class DebugWindow {

    private static JFrame    debugWindow  = null;
    private static JTextArea debugContent = null;

    public static void show() {
        debugWindow = new JFrame("Debug");
        debugWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        debugContent = new JTextArea("Debug messages go here!");
        debugWindow.add(debugContent, BorderLayout.CENTER);
        debugWindow.pack();
        debugWindow.setVisible(true);
    }
}

加载Google AppEngine Dev-Server的帮助程序类:

// other imports
import com.google.appengine.tools.development.DevAppServerMain;

public class DevServer {
    public static void launch(final String[] args, boolean waitFor) {
        Logger logger = Logger.getLogger("");
        logger.info("Launching AppEngine server...");
        Thread server = new Thread() {
            @Override
            public void run() {
                try {
                    DevAppServerMain.main(args);  // run DevAppServer
                } catch (Exception e) { e.printStackTrace(); }
            }
        };
        server.setDaemon(true);  // shut down server when rest of app completes
        server.start();          // run server in separate thread
        if (!waitFor) return;    // done if we don't want to wait for server
        URLConnection cxn;
        try {
            cxn = new URL("http://localhost:8888").openConnection();
        } catch (IOException e) { return; }  // should never happen
        boolean running = false;
        while (!running) {
            try {
                cxn.connect();  // try to connect to server
                running = true;
            } catch (Exception e) {}
        }
        logger.info("Server running.");
    }
}

我的main(…)方法如下所示:

public static void main(final String[] args) throws Exception {
    DevServer.launch(args, true);  // launch and wait for AppEngine dev server
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            DebugWindow.show();  // create and show debug window
        }
    });
}

有了这个,我对Swing Eventloop有一些非常奇怪的行为:

>首先,Swing的工作方式:如果我在main(…)中注释掉DevServer.launch(…)行,应用程序启动,显示调试窗口,继续运行,以及何时关闭调试窗口,它关闭了.
>如果我重新添加DevServer.launch(…),它会按预期启动服务器,然后立即退出(它可能还会短暂显示调试窗口,但它太快看不到).
>如果我在SwingUtilities.invokeLater(…)之后移动DevServer.launch(…)行,它会显示调试窗口,然后启动服务器,当服务器启动时,它会立即退出.
>现在它变得非常奇怪:如果我将行更改为DevServer.launch(args,false),即我不等待服务器实际启动,而只是让我的main(…)方法立即完成,调试窗口显示,服务器正确加载,应用程序继续运行,但是如果关闭调试窗口则不退出?!
>如果我还将JFrame.DISPOSE_ON_CLOSE更改为JFrame.EXIT_ON_CLOSE,则调试窗口显示,服务器正确加载,应用程序继续运行,如果我关闭调试窗口,它将正确退出.

知道Swing事件循环在这里发生了什么吗?我很难过……有什么东西会导致Swing事件循环提前终止(场景2和3)?多线程应用程序是否阻止Swing检测到最后处理的窗口(方案4)?

供参考,here is the source of the Google AppEngine Dev Server.

最佳答案
项目#4和#5实际上是预期的行为.当放置最后一个Swing窗口时,Java / Swing应用程序不会停止,但是当最后一个线程停止执行时.这两个条件对于单线程应用程序是等效的,但对于多线程应用程序则不是.

至于#1,#2和#3:通过AppEngine Dev Server代码查看,我注意到有相当数量的System.exit(int)调用.其中一个可能是罪魁祸首.如果您显示的代码是相关的,那么可能会调用违反的System.exit以响应if(!waitFor)返回后建立的连接; (由于#4)

转载注明原文:Java Swing应用程序意外终止 - 代码日志