Ruben de Groot Ruben de Groot - 2 months ago 19
Java Question

Start a server from event handler in swing

So I am making a application, which starts a server when I press the start button. I am new into networking in Java so the server is very basic. When I try to start the server the application freezes. I know I have to use multi-threading to solve it, but I don't know how to multi-thread. Here is a little code snippet of the event for the start button:

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == startButton) {

appendToChat("CONSOLE > Trying to start server...");
server = new Server(4454);

inputField.setEditable(true);
stopButton.setEnabled(true);
startButton.setEnabled(false);
}


And here is the code from the server:

public class Server {

private ServerSocket serverSocket;
private Socket socket;
private Scanner scanner;
private PrintStream stream;

private int port;

private boolean succes = false;

public Server(int port) {
this.port = port;
init();
}

public void sendToClient(String value) {
stream.println(value);
}

public String getMessage() {
if(scanner == null) {
return "reader NullPointerException";
}
return scanner.nextLine();
}

public int getPort() {
return port;
}

public void stop() {
try {
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
scanner.close();
stream.close();
}

public boolean isSucces() {
return succes;
}

private void init() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
scanner = new Scanner(socket.getInputStream());
stream = new PrintStream(socket.getOutputStream());
succes = true;
} catch (Exception e) {
succes = false;
e.printStackTrace();
}

}

}

Answer

Your problem is that you are blocking the UI thread in the call to ServerSocket.accept(). You need to call this on a separate thread so that the UI thread can proceed with its operations.

Change your init() method code into an inner Runnable class, and run that in init()

private void init() {
  new Thread(new SocketRunner()).start();
}

private class SocketRunner implements Runnabled {
    public void run() {
      try {
        serverSocket = new ServerSocket(port);
        socket = serverSocket.accept();
        scanner = new Scanner(socket.getInputStream());
        stream = new PrintStream(socket.getOutputStream());
        succes = true;
      } catch (Exception e) {
        succes = false;
        e.printStackTrace();
      }
    }
}