I created a Client/Server Chat Application with JavaFX. My ServerController creates a Server Object when the 'Start Server'-Button is pressed which is running on a separate Thread.
Here is my Problem:
Whenever I just close the Window with the default 'x'-Button the Server-Thread terminates but doesn't inform the active Clients that the Server terminated. I need to inform the Clients that the Server is shutdown like I do with my 'Stop-Server'-Button. My Server holds a reference to the Controller Object.
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");
}
}
Here is my 'Stop-Server'-Button that informs all Client, that the Server will be shutdown and then closes all Sockets and stuff like that.
@FXML
public void stopButtonAction(ActionEvent e) {
if (started) {
server.setRunning(false);
chatEvent_txt.setText("Server wurde gestoppt\n");
started = false;
}
}
The method setRunning(); will just set a variable to false so that the thread will leave the while-loop that accepts new clients. When the while loop is left the Server will send a Message to all Clients so they know the Server will be shutdown.
run-Method on my Server:
@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();
}
}
How can I tell the 'x'-Button to do the same as my "Stop Server"-Button?
Refactor it as
@FXML
public void stopButtonAction(ActionEvent e) {
shutdown();
}
public void shutdown() {
if (started) {
server.setRunning(false);
chatEvent_txt.setText("Server wurde gestoppt\n");
started = false;
}
}
and then when you load and display the FXML, you can do:
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());
If you need the window not to close when the close button is pressed (e.g. if you need to wait for everything to shutdown gracefully before closing the window programmatically), you can call e.consume()
in the onCloseRequest
handler.