javagetter-setterkryonet

Why are my getters returning null when I try to send to the server?


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);
  }
 }

Solution

  • 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);
    });