Bobdabiulder Bobdabiulder - 5 months ago 25
Java Question

Calling non-static method (in a different class) from static

I've done some looking around on here for a solution, but I can't find one. I tried these ones and many others, and I run into the same issue.

I am trying to make a simple text game, and I run into the issue where I have a main class, and a class called "gameboard" that I have as an array defined like this:

static GameBoard[] gameboard = new GameBoard[9];


Now, this works fine until I try to change the characteristics of a single one of these array objects. I will do:

gameboard[input].setState(2);


and the specific instance of gameboard that should change will not be the only one: all of them change when I do this. It's weird. Only
gameboard[**input**]
should change, not all 9 of the gameboard instances. EVERY variable and method I have is "static", but because of the main method (public static void main...), everything seems to have to be static. How do I get rid of all this static?

GameBoard Class

package com.name.tictactoe;

public class GameBoard {
char[] States = {'N','X','O'};
char state;

public void setState(int s){
state = States[s];
}
public char getState(){
return state;
}
}


Main class (called Game)

package com.name.tictactoe;

import java.util.Scanner;

public class Game {

static boolean turn, win;
static GameBoard[] gameboard;
static Scanner kb = new Scanner(System.in);
static int input;

public static void main(String[] args){
gameboard = new GameBoard[9];
reset();
displayStates();
askTurn();
displayStates();
askTurn();

}

public static void askTurn() {
System.out.println();
System.out.println();
System.out.println("Where do you want to go? Use the numbers shown, where the first segment is the top and the last is the bottom - left to right.");
input = kb.nextInt();
if(input > 8){
System.out.println("Input out of bounds. Game over by default.");
try {
Thread.sleep(1000000000);} catch (InterruptedException e) {e.printStackTrace();}
}
gameboard[input].setState(2);
}

public static void reset(){
for(int i = 0; i < 9; i++){
gameboard[i].setState(0);
}
}

public static void displayStates(){
for(int i = 0; i < 9; i++){
System.out.print(gameboard[i].getState() + " ");
if(i ==2 || i ==5){
System.out.print(" II ");
}
}
System.out.println();
for(int i = 0; i < 9; i++){
System.out.print(i + " ");
if(i ==2 || i ==5){
System.out.print(" II ");
}
}
System.out.println();
}


}

UPDATE: The current answers don't work. Although Eclipse doesn't realize this, making GameBoard non-static causes null pointer exceptions when any method in it is referenced.

Answer

A static variable belongs to the class, not the object, so of course all of your GameBoards are being affected!

Just because you're in a static method doesn't mean you can't manipulate instance variables. First, make everything in your GameBoard class non-static (unless you really do need some of the values shared across all instances). This includes your instance variables and your getter/setter methods.

If your program works exclusively from the main method, then keep your GameBoard[] object static. Then, when you make that method call:

gameboard[input].setState(2);

This will change only the state of the GameBoard at index input.

Edit:

To instantiate your GameBoard[] with basic GameBoard objects inside of it, you can do this at the beginning of your main method:

for(int x=0; x<gameboard.length; x++) {
    gameboard[x] = new GameBoard(); //Assuming you want to use the default constructor
}