JavaFX-如何在退出应用程序之前关闭所有正在运行的线程?
我用JavaFX创建了一个客户机/服务器聊天应用程序。My ServerController在按下“启动服务器”按钮时创建一个服务器对象,该按钮在单独的线程上运行 我的问题是: 只要我用默认的“x”按钮关闭窗口,服务器线程就会终止,但不会通知活动客户端服务器已终止。我需要通知客户端服务器已关闭,就像我使用“停止服务器”按钮一样。我的服务器保存对控制器对象的引用JavaFX-如何在退出应用程序之前关闭所有正在运行的线程?,java,javafx,exit,java-threads,Java,Javafx,Exit,Java Threads,我用JavaFX创建了一个客户机/服务器聊天应用程序。My ServerController在按下“启动服务器”按钮时创建一个服务器对象,该按钮在单独的线程上运行 我的问题是: 只要我用默认的“x”按钮关闭窗口,服务器线程就会终止,但不会通知活动客户端服务器已终止。我需要通知客户端服务器已关闭,就像我使用“停止服务器”按钮一样。我的服务器保存对控制器对象的引用 public class ServerController { @FXML TextArea chatEvent_txt; @FXML
public class ServerController {
@FXML
TextArea chatEvent_txt;
@FXML
Button start_btn;
@FXML
Button stop_btn;
private Server server;
private boolean started = false;
private StringBuffer chatEvents = new StringBuffer("");
/**
* @param e
*/
@FXML
public void startButtonAction(ActionEvent e) {
if (!started) {
this.server = new Server(this);
new Thread(server).start();
started = true;
chatEvents = chatEvents.append("Server started.." + "\n");
chatEvent_txt.setText(chatEvents.toString());
} else {
chatEvent_txt.setText("Server already started\n");
}
}
这是我的“停止服务器”按钮,它通知所有客户端服务器将关闭,然后关闭所有套接字之类的东西
@FXML
public void stopButtonAction(ActionEvent e) {
if (started) {
server.setRunning(false);
chatEvent_txt.setText("Server wurde gestoppt\n");
started = false;
}
}
方法setRunning();只需将一个变量设置为false,这样线程就会离开接受新客户机的while循环。当while循环结束时,服务器将向所有客户端发送一条消息,以便它们知道服务器将关闭
在我的服务器上运行方法:
@Override
public void run() {
try {
serverSocket.setSoTimeout(500);
while (running) {
try {
clientSocket = serverSocket.accept();
new Thread(new Listener(clientSocket, this)).start();
} catch (IOException e) {
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
try {
broadcastMessage(new Message(Message.Type.DISCONNECT_OK, "Server"));
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
我如何让“x”按钮与我的“停止服务器”按钮执行相同的操作?将其重构为
@FXML
public void stopButtonAction(ActionEvent e) {
shutdown();
}
public void shutdown() {
if (started) {
server.setRunning(false);
chatEvent_txt.setText("Server wurde gestoppt\n");
started = false;
}
}
然后,当您加载并显示FXML时,您可以执行以下操作:
FXMLLoader loader = new FXMLLoader(getClass().getResource("/path/to/fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
someStage.setScene(scene);
ServerController controller = loader.getController();
someStage.setOnCloseRequest(e -> controller.shutdown());
如果您需要在按下关闭按钮时不关闭窗口(例如,如果您需要在以编程方式关闭窗口之前等待一切正常关闭),则可以调用
e.consume()
在onCloseRequest
处理程序中。您应该在该处理程序中实现处理程序并优雅地关闭服务器。虽然给出的答案有效,但我更喜欢a,如果程序使用Ctrl+C停止,也会调用a。@MalaKa很难获得与FX Toolkit正确交互的关闭挂钩(甚至要知道正确的实现是什么)。事实上,明确声明“尝试使用其他基于线程的服务,例如AWT事件调度线程,可能会导致死锁。”@GurV您链接的问题是关于退出正在运行的线程,而不是关于截取窗口中的关闭按钮。我不知道这是如何重复的。谢谢,这是有效的。我通过覆盖应用程序类中的stop()方法解决了这一问题。但我不确定这是否正确。