-1

I am attempting to write a program that will allow a user to input four characteristics of a "Player" object and add that object to an array list of other Player objects. However, it seems that all Player objects are treated as the same.

I suspect that all the program is doing is filling the arraylist with many references to the same object with the same instance variables, but I cannot figure out a way to fill the arraylist with discrete objects that all have different instance variables.

If I try to make all fields in the Player class nonstatic I get the error "nonstatic variable/method cannot be referenced from a static context".

Driver Class Code

package playerdatamanager;

import java.util.*;

public class MainMenu {

    public static void main(String[] args) {
        
        ArrayList<Player> playerRoster = new ArrayList<>();

        Scanner input = new Scanner(System.in);

        int exitMenu = 0;

        while (!"7".equals(exitMenu)) {

            System.out.println("Please choose an option or press 7 to exit [1-7].");
            System.out.println("1. " + "Add a player");
            System.out.println("2. " + "Update a player");
            System.out.println("3. " + "Delete a player");
            System.out.println("4. " + "List all players");
            System.out.println("5. " + "Calculate the average BMIs for the players");
            System.out.println("6. " + "Display the details of the tallest player");
            System.out.println("7. " + "Exit");

            int menuOption = Integer.parseInt(input.nextLine());

            

            switch (menuOption) {
                case (1):

                    System.out.println("Please enter the name of the player.");

                    String newPlayerName = input.nextLine();

                    System.out.println("Please enter the jersey number of the player.");

                    int newPlayerJerseyNumber = Integer.parseInt(input.nextLine());

                    System.out.println("Please enter the height of the player.");

                    double newPlayerHeight = Double.parseDouble(input.nextLine());

                    System.out.println("Please enter the weight of the player.");

                    double newPlayerWeight = Double.parseDouble(input.nextLine());

                    playerRoster.add(new Player(newPlayerName, newPlayerJerseyNumber, newPlayerHeight, newPlayerWeight));

                    break;

                case (2):
                    System.out.println("Which player would you like to update?");

                    System.out.println(playerRoster.toString());

                    int playerIndex = Integer.parseInt(input.nextLine());

                    System.out.println("Selected" + playerRoster.get(playerIndex).toString());

                    System.out.println("Enter the value you would like to change[1. name ,2. jersey number,3. weight,4. height]");

                    int userValueUpdate = Integer.parseInt(input.nextLine());

                    switch (userValueUpdate) {

                        case (1):
                            System.out.println("Please enter the new value for the player's name.");

                            Player.setName(input.nextLine());

                            break;

                        case (2):
                            System.out.println("Please enter the new value for the player's jersey number.");

                            Player.setJerseyNumber(Integer.parseInt(input.nextLine()));

                            break;

                        case (3):

                            System.out.println("Please enter the new value for the player's weight.");

                            Player.setWeightInPounds(Double.parseDouble(input.nextLine()));

                            break;

                        case (4):
                            System.out.println("Please enter the new value for the player's height.");

                            Player.setHeightInInches(Double.parseDouble(input.nextLine()));

                            break;
                    }

                    break;
                case (3):

                    System.out.println("Which player would you like to delete?");

                    int userDeletion = Integer.parseInt(input.nextLine());

                    playerRoster.toString();

                    playerRoster.remove(userDeletion);

                    break;

                case (4):

                for (int i = 0; i < playerRoster.size();i++) {
                    
                    
                    
                    
                   
                    
                    
                    System.out.print("Name: " + playerRoster.get(i).getName() + "\nHeight: " + Double.toString(playerRoster.get(i).getHeight()) + "\nWeight: " + Double.toString(playerRoster.get(i).getWeight()) + "\nJersey Number: " + Integer.toString( playerRoster.get(i).getJerseyNumber()) + "\n\n");
                }

                    break;



            }
        } 
    }
}

Player class code

package playerdatamanager;

/**
 *
 * @author Austin
 */
public class Player {

    private static String name;
    private static int jerseyNumber;
    private static double height;
    private static double weight;

    /**
     * The default constructor for the Player object.
     */
    public Player() {
    }

    /**
     * Overloaded constructor to initialize Player object with user values.
     *
     * @param name The name of the Player
     * @param jerseyNumber The Jersey Number of the Player
     * @param height The height of the Player
     * @param weight
     */
    public Player(String name, int jerseyNumber, double height, double weight) {
        this.name = name;
        this.jerseyNumber = jerseyNumber;
        this.height = height;
        this.weight = weight;
    }

    /**
     * method to calculate the BMI of a given player.
     *
     * @param height The height of a player.
     * @param weight The weight of a player.
     * @return the BMI of a player.
     */
    /**
     * setter method to set the player's name.
     *
     * @param userName The name given by the user.
     */
    public static void setName(String userName) {
        name = userName;
    }

    /**
     * setter method to set a player's jersey number.
     *
     * @param userJerseyNumber The jersey number given by the user.
     */
    public static void setJerseyNumber(int userJerseyNumber) {
        jerseyNumber = userJerseyNumber;
    }

    /**
     * setter method to set a player's height in inches.
     *
     * @param userHeight The height in inches given by the user.
     */
    public static void setHeightInInches(double userHeight) {
        height = userHeight;
    }

    /**
     * setter method to set a player's weight in pounds.
     *
     * @param userWeight The weight in pounds given by the user.
     */
    public static void setWeightInPounds(double userWeight) {
        weight = userWeight;
    }

    /**
     * getter method to retrieve the name of a player.
     *
     * @return The player's name.
     */
    public static String getName() {
        return name;
    }

    /**
     * getter method to retrieve the jersey number of a player.
     *
     * @return The player's jersey number.
     */
    public static int getJerseyNumber() {
        return jerseyNumber;
    }

    /**
     * getter method to retrieve the weight in pounds of a player.
     *
     * @return The player's weight in pounds.
     */
    public static double getWeight() {
        return weight;
    }

    /**
     * getter method to retrieve the height in inches of a player.
     *
     * @return The player's height in inches.
     */
    public static double getHeight() {
        return height;
    }

    public static double BMICalculation() {
        double BMI;

        BMI = 703 * (getWeight() / (getHeight() * getHeight()));

        return BMI;
    }

    public static void playerRosterToString(double height, double weight, int jerseyNumber, String name) {

        String playerStats = "Name: " + name + "\nHeight: " + Double.toString(height) + "\nWeight: " + Double.toString(weight) + "\nJersey Number: " + Integer.toString(jerseyNumber);

        System.out.print(playerStats);

    }

}

The user should be able to input a player's name, jersey number, weight, and height. Then the user should be able to read it anytime they like.

However, if a user inputs player name "Babe Ruth", jersey number 1, weight 155, and height 70 that information will be stored. Then, if a user inputs player name "Joe Dimaggio", jersey number 2, weight 170, and height 75 the program doesn't store any information for Joe Dimaggio, but it will store Babe Ruth's attributes.

If a user lists all players, the output is:

Name: Babe Ruth

Jersey number: 1

Weight: 155

Height: 70

Name: Babe Ruth

Jersey number: 1

Weight: 155

Height: 70

when it should be:

Name: Babe Ruth

Jersey number: 1

Weight: 155

Height: 70

Name: Joe Dimaggio

Jersey number: 2

Weight: 170

Height: 75

8
  • 4
    Remove static from all the class member variables. Go back and review what static means when applied to class members. Commented Apr 25 at 21:45
  • If I do that then I can't use the class in the main method with my current understanding. Commented Apr 25 at 21:47
  • 4
    Your current understanding is incorrect. They're private, so if you need access to them, add "getter" methods for the attributes you need to retrieve. If that's not the answer you need, explain why you think you can't use it in main() Commented Apr 25 at 21:51
  • 3
    Well, edit your question to include that information and identify which line gives the error. I think what you need to do is remove ALL static qualifiers in the Player class. Commented Apr 25 at 21:57
  • 1
    Presumably, you'll need to create a variable of type Player, and use new somewhere in there... Commented Apr 25 at 21:57

1 Answer 1

3

You're onto something!

However, you are not referencing the same Player over and over again. Instead, you do have different Player-objects, but there is certainly something going on...

Have a look at your setX-methods. What fields are being updated? Here's the name of the player: private static String name;

Recall; static means that the field is not specific for the one Player, but for "all" Player-objects. (Correction: it belongs to the class of Player. So, if a method/field is public and static, it can be used without ever constructing an Object of that class).

Thus, when you use the set-method or construct new Player-objects, you are re-assigning these static-fields. Hence, why all Player-object appear to have the same field-values.

Solution

The fields should not be static - unless you want all Player-objects to have the same field value for something.

Furthermore, the methods which are referencing these non-static fields, such as the set- and get-methods should also be non-static. Otherwise, Java will throw a compilation error.

So, to use non-static methods, you must have an instantiated Player-object. Example, where we use the empty constructor, to then manually set the name of the player using the corresponding set-method:

// Creating a Player without a name
Player someNewPlayer = new Player();

// Setting the 'name'-field for the Player 'someNewPlayer'
someNewPlayer.setName("John Doe");

//  Let's check if the name changed
System.out.println("The player's name is: " + someNewPlayer.getName());
// This should say "John Doe"
9
  • Thank you for your response, but unfortunately I have already tried setting all of the fields to be non static, which gives me the error "cannot reference nonstatic variable/method from a static context". I cannot make the main method nonstatic so it seems to me there is no way around that error. Commented Apr 25 at 22:00
  • 1
    Great! So, from a non-static context we can set static-variables. However, you cannot do the inverse. Have a look at your set-methods - those are static! This is the reason for the error(s). Since these set/get-methods are used to interact with non-static variables, these methods should not be static either.
    – Chrimle
    Commented Apr 25 at 22:03
  • I have removed all static qualifiers in the Player class, but I cannot reference any of the setter methods from the main method because it is static. Commented Apr 25 at 22:05
  • Correct, for example Player.setName(input.nextLine()); is no longer static, so we cannot access it directly by referencing the Player-class. Instead, we must invoke the setName()-method on a Player-object. I would suggest where you instantiate a player (new Player(...)), create a temporary variable (name it newPlayer) so that you can set the name of that particular player - via newPlayer.setName("A new name").
    – Chrimle
    Commented Apr 25 at 22:09
  • 1
    From what I can tell, if you only use option 1 - the create new player. Then it should work as expected. When you want to update the name of an existing Player, you will not use Player.setName(input.nextLine()), but instead use: playerRoster.get(playerIndex).setName((input.nextLine()). This should be updating the name of the selected player.
    – Chrimle
    Commented Apr 25 at 22:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.