我正嘗試在Java中編寫Swing應用程序,該應用程序也運行Google AppEngine Dev-Server(請參閱Developing a Java Application that uses an AppEngine database)並且遇到Swing Eventloop出現的奇怪問題。Java Swing應用程序意外終止
我有以下兩類:
一個調試窗口,這將最終接收日誌消息,等:
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);
}
}
加載了谷歌的AppEngine開發,服務的輔助類:
// 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的事件循環一些非常奇怪的現象:
- 首先,搖擺的方式應該工作:如果我註釋掉線
DevServer.launch(...)
在main(...)
,應用程序啓動,顯示了調試窗口繼續運行,當我關閉調試窗口時,它關閉。 - 如果我重新添加
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。
當您捕捉到「應該永遠不會發生」的異常時, IOException',將它重新拋出爲'RuntimeException'總是一個好主意,只是爲了證明你的觀點。淺色從來不是一個好主意 –
@ c.s。同意。我實際上爲我自己定義了一個'ShouldNeverHappenException'對象,我總是使用它。我只是從代碼示例中刪除它,因爲我不想發佈另一個類的完整性... –