Я пытаюсь написать приложение Swing на Java, которое также запускает 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);
}
}
Помощника-класс, который загружает Google AppEngine Dev-сервер:
// 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
}
});
}
С этим я получаю некоторые очень странное поведение в отношении свинг Eventloop:
- Во-первых, как свинг должен работать: Если я закомментируйте строку
DevServer.launch(...)
вmain(...)
, запуске приложения, показывает отладки окно, продолжает работать, и когда я закрываю окно отладки, он отключается. - Если я снова добавлю
DevServer.launch(...)
, он запускает сервер, как ожидалось, а затем немедленно завершает работу (возможно, он также отобразил окно отладки ненадолго, но это слишком быстро видно). - Если я переведу
DevServer.launch(...)
послеSwingUtilities.invokeLater(...)
, он отображает окно отладки, затем запускает сервер, и когда сервер встает, он немедленно завершает работу. - Теперь это действительно странно: если я сменил строку на
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», чтобы доказать свою точку зрения. Shallowing никогда не бывает хорошей идеей –
@ c.s. Согласовано. Фактически я определил объект 'ShouldNeverHappenException' для себя именно по этой причине, который я всегда использую. Я просто удалил его из образца кода, так как я не хотел публиковать еще один класс для полноты ... –