0

I'm trying to build some Chatting Application with Javafx and java.net networking package. I want the text the User typed in the textfield to be send from the client to the server and from there back to the client and eventually showing up in the textarea of the application. But the application is crashing after I press Enter when I typed in a text in the TextField. So in the "handle"-method of the EventHandler there must be the error. Also the application is crashing before the input-text gets cleared. The application is not responding --> error window pops up.Application is not responding

Client-side Code:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.Parent;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.*;

public class ChatAppClient extends Application {

private TextArea messages = new TextArea();
private TextField input;
private static String ipAdress = null;
private DataInputStream dis;
private DataOutputStream dos;
private static Socket client;

public Parent mainScene() throws UnknownHostException, IOException {

  // Getting IP-Adress from a different file as a String

  String userDir = System.getProperty("user.dir");
  File file = new File(userDir + "\\..\\IPAdress.txt");
  RandomAccessFile raFile = new RandomAccessFile(file, "rw");
  raFile.seek(0);
  ipAdress = raFile.readLine();
  raFile.close();

  // Initialising new Socket

  client = new Socket(ipAdress, 5000);
  System.out.println("Connected to Server.");

  // Defining JavaFx Application-Layout

  messages.setPrefHeight(220);
  input = new TextField();

  VBox root = new VBox(20, messages, input);
  root.setPrefSize(400, 400);

  // Setting up action for Textfield when pressing Enter

  input.setOnAction(new EventHandler<ActionEvent>() {

     @Override
     public void handle(ActionEvent event) {

        try {

           // Defining and initialising Input-String

           String message = "Client: ";
           message += input.getText();

           // Opening OutputStream for String to send it to the server
           dos = new DataOutputStream(client.getOutputStream());

           // Giving the String to the OutputStream
           dos.writeBytes(message);

           // Clearing the Textfield from Input-Text
           input.clear();

           // Setting up InputStream for the Socket to receive the String back from the
           // server

           dis = new DataInputStream(client.getInputStream());

           // Reading String from InputStream

           String s = dis.readLine();

           // Closing In-and OutputStreams + Socket

           dos.close();

           // Showing the String in the TextArea "messages"

           messages.appendText(s + "\n");
        } catch (IOException ioE) {
           ioE.printStackTrace();
        }
     }
  });

  return root;

  }

  public void start(Stage mainStage) {

  try {
     mainStage.setScene(new Scene(mainScene()));
     mainStage.show();

  } catch (UnknownHostException uHE) {
     uHE.printStackTrace();
  } catch (IOException iOE) {
     iOE.printStackTrace();
  }

  }

  public static void main(String[] args) {
  try {
     launch(args);
     client.close();
  } catch (IOException ioE) {
     ioE.printStackTrace();
  }
  }

  }

Server-side Code:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatAppServer {
public static void main(String[] args) {

    try {

        // Defining/ Initialising new ServerSocket

        ServerSocket caServerSocket = new ServerSocket(5000);
        System.out.println("Waiting for Client...");
        Socket nSocket = caServerSocket.accept();
        System.out.println("Client connected.");

        // Setting up InputStream for the ServerSocket to receive the message String

        DataInputStream clientMessages = new DataInputStream(nSocket.getInputStream());
        String s = clientMessages.readLine();

        // Testing if the Input String got received

        System.out.println(s);

        // Setting up OutputStream to send back the String

        DataOutputStream clientMessagesBack = new DataOutputStream(nSocket.getOutputStream());
        clientMessagesBack.writeBytes(s);

        caServerSocket.close();

    } catch (IOException ioE) {
        ioE.printStackTrace();
    }
}
}
Lit
  • 13
  • 4
  • 1
    The line `String s = dis.readLine();` blocks execution until it reads from the socket. Since you're executing that on the FX Application Thread, that means that thread is blocked until it receives a message, preventing it from doing the things it normally does (such as rendering the UI and listening for user input, etc.). Hence the entire UI freezes. You need to move the code that waits for messages from the server to a background thread - see e.g. [here](https://stackoverflow.com/q/30249493). Threading is complex and extremely challenging for new programmers. – James_D Apr 19 '20 at 14:02
  • There may be other issues too, e.g. you should [`flush()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/io/DataOutputStream.html#flush()) the data output stream on the server after sending a message; since the client is using `readLine()` I think you also need to be sure to send a line termination at the end of the message. – James_D Apr 19 '20 at 14:05
  • Thank you, you were right with your first comment @James_D – Lit Apr 21 '20 at 22:13

0 Answers0