簡體   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