繁体   English   中英

Java Swing应用程序意外终止

[英]Java Swing application terminates unexpectedly

我正在尝试用Java编写一个Swing应用程序,该应用程序还运行Google AppEngine Dev-Server(请参阅开发使用AppEngine数据库的Java应用程序 ),并且遇到了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有一些非常奇怪的行为:

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

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

作为参考,以下是Google AppEngine Dev Server的来源

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM