The title might not be very clear, and I not sure how I should phrase my question, but in short I am trying to create a "chat" program in java. I use 2 different files ChatServer and ChatClient.
How the program works is that you first open ChatServer and then ChatClient in order to connect to ChatServer. To Connect you need first to write a username in the first TextField and press enter. Then the program tries to connect you to the server, and here is where the problem starts.
Everytime I try to connect to the server I am getting nullpointerexception, and I can't understand why. I have tried for a long time to understand, but I am unable to see the error.
The point of the program is that mutliple ChatClients can connect to the ChatServer (Max 5 people) and write to each other. I know the question is very specific and I am hoping if anyone can point me in the right direction I would be very happy!
ChatServer
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class ChatServer extends Application
{
private ArrayList<ObjectOutputStream> outputToUsers;
private TextArea taServer = new TextArea();
private static final int MAX_USERS = 5;
private boolean acceptingNewUsers = true;
private int connectedUsers = 0;
private static final int port = 4999;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage)
{
initializePrmaryStage(primaryStage);
new Thread( () ->
{
try
{
// Create a server socket
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(port);
Platform.runLater(() -> taServer.appendText(new Date() + ": Server started at socket: " + port + '\n'));
acceptUsers();
while (true)
{
if (acceptingNewUsers)
{
// Listen for a new connection request
Socket socket = serverSocket.accept();
connectedUsers++;
if (connectedUsers == MAX_USERS)
refuseNewUsers();
// Create and start a new thread for the connection
new Thread(new AddUserToChat(socket)).start();
}
}
}
catch(IOException ex)
{
System.err.println(ex);
}
}).start();
}
private void initializePrmaryStage(Stage stage)
{
taServer.setMinHeight(450);
// Create a scene and place it in the stage
Scene scene = new Scene(new ScrollPane(taServer), 450, 400);
stage.setTitle("ChatServer"); // Set the stage title
stage.setScene(scene); // Place the scene in the stage
stage.show(); // Display the stage
}
private void acceptUsers()
{
acceptingNewUsers = true;
Platform.runLater(() -> taServer.appendText(new Date() + ": " + "Accepting users" + '\n'));
}
private void refuseNewUsers()
{
acceptingNewUsers = false;
Platform.runLater(() -> taServer.appendText("Maximum user capacity reached." + '\n'));
}
private void writeToAll(String s)
{
try
{
for (int x = 0; x < outputToUsers.size(); x++)
{
outputToUsers.get(x).writeObject(s);
outputToUsers.get(x).flush();
}
} catch (IOException ex)
{
ex.printStackTrace();
}
}
private void writeToLog(String s)
{
Platform.runLater(() ->
{
taServer.appendText(s);
});
}
private class AddUserToChat implements Runnable
{
private ObjectInputStream fromUser;
private ObjectOutputStream toUser;
private String username;
private Socket userSocket;
@SuppressWarnings("unused")
public AddUserToChat(Socket userSocket)
{
this.userSocket = userSocket;
connectedUsers++;
}
@Override
public void run()
{
try
{
establishUserConnection();
readMessagesFromUser();
}
catch (Exception e)
{
System.err.println(e.getMessage());
removeUser();
}
}
/*
* Connects user to server
* @throws IOException if {@link ObjectInputStream#readUTF()} encounters an error
*/
private void establishUserConnection() throws IOException
{
// Get input and output streams from socket
toUser = new ObjectOutputStream(userSocket.getOutputStream());
fromUser = new ObjectInputStream(userSocket.getInputStream());
// Read and save username and save OOS to user in outputToUsers in ChatServer class
username = fromUser.readUTF();
outputToUsers.add(toUser);
writeToLog(username + " joined the chat.");
writeToAll(username + " joined the chat.");
}
/**
* Removes user from server
*/
private void removeUser()
{
// Decrease user counter and remove OOS to user
connectedUsers--;
outputToUsers.remove(toUser);
writeToLog(username + " left the chat.");
writeToAll(username + " left the chat.");
// If server doesn't accept new users, start accepting them once again
if (!acceptingNewUsers) acceptUsers();
}
/**
* Continually read messages from user
*
* @throws IOException if {@link ObjectInputStream#readUTF()} encounters an error
*/
private void readMessagesFromUser() throws IOException
{
while (true)
writeToAll(String.format("%s wrote: %s", username, fromUser.readUTF()));
}
}
}
ChatClient
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class ChatClient extends Application
{
private ObjectOutputStream toServer = null;
private ObjectInputStream fromServer = null;
private GridPane gridpane = new GridPane();
private BorderPane mainPane = new BorderPane();
private TextField tfUsername = new TextField();
private TextField tfUserInput = new TextField();
private TextArea ta = new TextArea();
private String username = "";
private String userinput = "";
private Socket socket;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
// Panel p to hold the label and text field
BorderPane paneForTextField = new BorderPane();
paneForTextField.setPadding(new Insets(5, 5, 5, 5));
paneForTextField.setStyle("-fx-border-color: green");
gridpane.add(tfUsername, 0, 0);
gridpane.add(tfUserInput, 0, 1);
initializeUsernameTextField();
initializeUserInputTextField();
tfUserInput.setPrefWidth(400.0);
gridpane.setPrefWidth(450.0);
gridpane.setVgap(5.0);
gridpane.setHgap(25.0);
gridpane.setAlignment(Pos.CENTER);
paneForTextField.setBottom(gridpane);
ta.setPrefHeight(450);
mainPane.setCenter(new ScrollPane(ta));
mainPane.setBottom(paneForTextField);
initializePrimaryStage(primaryStage);
tfUsername.setOnAction(e ->
{
if (!tfUsername.getText().equals(""))
{
username = tfUsername.getText().trim();
connecToServer();
}
});
if (!username.equals(""))
{
tfUserInput.setOnAction(e ->
{
// Get user input
String UserInput = tfUserInput.getText();
// Send string
sendToServer(UserInput);
// Get string
receiveDataFromServer();
writeToLog(userinput);
});
}
}
private void initializeUsernameTextField()
{
tfUsername.setPrefWidth(400.0);
tfUsername.promptTextProperty().set("Enter username here...");
}
private void initializeUserInputTextField()
{
tfUserInput.setPrefWidth(400.0);
tfUserInput.promptTextProperty().set("Enter message here...");
}
private void initializePrimaryStage(Stage stage)
{
// Create a scene and place it in the stage
Scene scene = new Scene(mainPane, 450, 400);
stage.setTitle("Chat Client"); // Set the stage title
stage.setScene(scene); // Place the scene in the stage
stage.show(); // Display the stage
}
private BorderPane getBorderPane() {return mainPane;}
private void connecToServer()
{
establishServerConnection();
}
private void establishServerConnection()
{
try
{
socket = new Socket("localhost", 4999);
fromServer = new ObjectInputStream(socket.getInputStream());
toServer = new ObjectOutputStream(socket.getOutputStream());
sendToServer(username);
}
catch (IOException ex)
{
ta.appendText(ex.toString() + '\n');
}
}
private void receiveDataFromServer()
{
try
{
userinput = fromServer.readUTF();
} catch (IOException ex)
{
System.err.println(ex);
}
}
private void sendToServer(String s)
{
try
{
toServer.writeObject(s);
toServer.flush();
}
catch (IOException ex)
{
System.err.println(ex);
}
}
private void writeToLog(String s)
{
ta.appendText(tfUsername + "wrote: " + s + "\n");
}
}
TLDR;
Get nullpointerexception when trying to connect to the server, and I am unable to find the problem.
ERROR MESSAGE:
Exception in thread "Thread-5" java.lang.NullPointerException
at chapter19.ChatServer$AddUserToChat.removeUser(ChatServer.java:171)
at chapter19.ChatServer$AddUserToChat.run(ChatServer.java:143)
at java.lang.Thread.run(Unknown Source)
The property outputToUsers
is not inizialized and therefore equals null
.
This causes an exception to be thrown within AddUserToChat.run()
when calling establishUserConnection
for the statement outputToUsers.add(toUser)
.
This exception is caught so removeUser
is called.
Within this method, the statement outputToUsers.remove(toUser)
causes a new exception.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.