I know this question has been asked a countless number of times on here, and I've searched SO and other sources for a solution but I just can't resolve the error. I have a getter and setter for my ClientPlayer class attribute, the setter is called in the GUI when a certain button is called, and I would like to use the getter after a client connects and send the object to the server. Calling the method "this.client.sendTCP(clientPlayer.getPlayerName());" in the ClientController returns a nullPointerException.
Error: "JavaFX Application Thread" java.lang.IllegalArgumentException: object cannot be null.
My guess would be that I create a new instance of ClientPlayer one time too many thus returning null as my string playerName is originally set to none. However, I am not sure on how to go about solving the problem. I would really appreciate any help whatsoever.
public class ClientPlayer implements Serializable {
public ClientPlayer() {
}
private String playerName;
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerName() {
return this.playerName;
}
}
Below the relevant part of my GUI-code where I set a button to connect the to the server:
ClientPlayer clientPlayer = new ClientPlayer();
clientToGame.setOnAction((ActionEvent w) -> {
clientPlayer.setPlayerName(clientNameText.getText());
clientController.connect();
window.setScene(lobbyScene);
});
Here is the bit of my client-class where I try to get the name and send to server:
public class ClientController() {
ClientPlayer clientPlayer = new ClientPlayer();
public void connect() {
if (client.isConnected()) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "You are already connected to :{0}", config.getHost());
return;
}
this.client.start();
try {
this.client.connect(5000, config.getHost(), config.getTCPPort());
System.out.println("Successfully connected to " + config.getHost());
this.client.sendTCP(clientPlayer.getPlayerName());
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Server connection failed: {0}", ex.getMessage());
throw new RuntimeException(ex);
}
MessageRegistry.registerMessages(client.getKryo());
this.client.addListener(listener);
}
}
In your GUI, you create a ClientPlayer
instance and call setPlayerName()
on it. Then in ClientController
, you create a new ClientPlayer
instance (on which you never call setPlayerName()
), and call getPlayerName()
on it. Since you never set the player name for that instance, getPlayerName()
of course returns null.
You need to decide whose responsibility it is to "own" the ClientPlayer
instance. If it is the responsibility of the ClientController
, then either add a getClientPlayer()
method to ClientController
, and do
clientToGame.setOnAction((ActionEvent w) -> {
clientController.getClientPlayer().setPlayerName(clientNameText.getText());
clientController.connect();
window.setScene(lobbyScene);
});
and remove the ClientPlayer
entirely from your GUI class. If it is the responsibility of the GUI class to own it, then pass a reference to it to the connect()
method, and remove the ClientPlayer
field from the controller:
public class ClientController() {
// ClientPlayer clientPlayer = new ClientPlayer();
public void connect(ClientPlayer clientPlayer) {
if (client.isConnected()) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "You are already connected to :{0}", config.getHost());
return;
}
this.client.start();
try {
this.client.connect(5000, config.getHost(), config.getTCPPort());
System.out.println("Successfully connected to " + config.getHost());
this.client.sendTCP(clientPlayer.getPlayerName());
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Server connection failed: {0}", ex.getMessage());
throw new RuntimeException(ex);
}
MessageRegistry.registerMessages(client.getKryo());
this.client.addListener(listener);
}
}
and of course
clientToGame.setOnAction((ActionEvent w) -> {
clientPlayer.setPlayerName(clientNameText.getText());
clientController.connect(clientPlayer);
window.setScene(lobbyScene);
});