我是一位有用的助手,可以为您翻译文本。
我正在尝试使用Java编写一个Swing应用程序,该应用程序还运行Google AppEngine Dev-Server(请参见Developing a Java Application that uses an AppEngine database),但在Swing事件循环中遇到了奇怪的问题。
我有以下两个类:
1. 一个调试窗口,最终将接收日志消息等。
2. 一个主应用程序,它启动并运行Dev-Server。
一个帮助类,用于加载Google AppEngine Dev-Server:
我遇到了一些关于Swing事件循环的奇怪行为:
供参考,这是Google AppEngine Dev Server的源代码。
我正在尝试使用Java编写一个Swing应用程序,该应用程序还运行Google AppEngine Dev-Server(请参见Developing a Java Application that uses an AppEngine database),但在Swing事件循环中遇到了奇怪的问题。
我有以下两个类:
1. 一个调试窗口,最终将接收日志消息等。
2. 一个主应用程序,它启动并运行Dev-Server。
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事件循环的奇怪行为:
- 首先,Swing应该是这样工作的:如果我在
main(...)
中注释掉DevServer.launch(...)
这一行,应用程序会启动,显示调试窗口,继续运行,当我关闭调试窗口时,它会关闭。 - 如果我重新添加
DevServer.launch(...)
,它会如预期地启动服务器,然后立即退出(可能还会短暂显示调试窗口,但太快看不到)。 - 如果我将
DevServer.launch(...)
移动到SwingUtilities.invokeLater(...)
之后,它会显示调试窗口,然后启动服务器,当服务器启动后,它会立即退出。 - 现在变得非常奇怪:如果我将该行更改为
DevServer.launch(args, false)
,即我不等待服务器实际启动,而只是让我的main(...)
方法立即完成,调试窗口会显示,服务器会正确加载,应用程序会继续运行,但如果我关闭调试窗口,它不会退出?! - 然后,如果我还将
JFrame.DISPOSE_ON_CLOSE
更改为JFrame.EXIT_ON_CLOSE
,调试窗口会显示,服务器会正确加载,应用程序会继续运行,并且如果我关闭调试窗口,它会正确退出。
供参考,这是Google AppEngine Dev Server的源代码。
IOException
,将其重新抛出为RuntimeException
总是一个好主意,以证明你的观点。浅层抛出从来不是一个好主意。 - c.s.ShouldNeverHappenException
对象,我总是使用它。我只是从代码示例中删除了它,因为我不想为了完整性再发布另一个类... - Markus A.