1

I have made simple JFrame that works fine except when I am trying to access it from other classes it returns null. So I made getter for it (public static JFrame getWindow()) it returns null. If I set JFrame to public and try to access it that way it returns null. When I create it becomes null right after the game engine starts.

Main:

public class Main {

private static String title = "2D SquareWorld 0.";
private static String version = "";

private static JFrame window;
private static Container container;

public static void main(String[] args) {

    GameEngine game = new GameEngine();

    window = new JFrame();

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setTitle(title + Version.newVersion());
    window.setResizable(false);
    window.add(game);
    window.setSize(1000, 720);
    window.setLocationRelativeTo(null);
    window.setVisible(true);

    game.start();

}

public static Container getContainer() {

    return container;

}

public static JFrame getWindow() {

    return window;

}

}

GameEngine:

package GameEngine;

public class GameEngine extends Canvas implements Runnable, KeyListener,                                                       MouseListener, MouseMotionListener {

private static final long serialVersionUID = 1L;

private Thread thread;
private boolean running;

private GameStateManager gsm;

public GameEngine() {

    gsm = new GameStateManager();

}

public void start() {

    thread = new Thread(this, "Game");
    thread.start();

    running = true;

    init();

}

public void init() {

    Data.setValue("ScreenWidth", getWidth());
    Data.setValue("ScreenHeight", getHeight());

    addKeyListener(this);

}

public void update(double delta) {

}

public void render() {

    BufferStrategy bs = getBufferStrategy();

    if(bs == null) {

        createBufferStrategy(2);

        return;

    }

    Graphics g = bs.getDrawGraphics();
    Graphics2D g2 = (Graphics2D) g;

    g2.setColor(Color.white);
    g2.fillRect(0, 0, getWidth(), getHeight());

    gsm.draw(g2);

    g2.dispose();
    bs.show();

}

public void run() {

    long lastLoopTime = System.nanoTime();
    long lastFpsTime = 0;

    final int TARGET_FPS = Fps.TargetFPS;
    final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;   

    int CurrentFps = 0;

    while(running) {

        long now = System.nanoTime();
        long updateLength = now - lastLoopTime;

        lastLoopTime = now;

        double delta = updateLength / ((double) OPTIMAL_TIME);

        lastFpsTime += updateLength;

        CurrentFps++;

        if (lastFpsTime >= 1000000000) {

            Fps.FPS = CurrentFps;

            lastFpsTime = 0;
            CurrentFps = 0;

        }

        update(delta);

        render();

        try {

            if(((lastLoopTime-System.nanoTime() + OPTIMAL_TIME) / 1000000) >= 1) {

                Thread.sleep((lastLoopTime-System.nanoTime() + OPTIMAL_TIME) / 1000000);

            }

        }catch(InterruptedException IE) {

        }

    }

}

public void mouseDragged(MouseEvent me) {

}

public void mouseMoved(MouseEvent me) {

}

public void mouseClicked(MouseEvent me) {

}

public void mouseEntered(MouseEvent me) {

}

public void mouseExited(MouseEvent me) {

}

public void mousePressed(MouseEvent me) {

}

public void mouseReleased(MouseEvent me) {

}

public void keyPressed(KeyEvent ke) {

    gsm.keyPressed(ke.getKeyCode());

}

public void keyReleased(KeyEvent ke) {

}

public void keyTyped(KeyEvent ke) {

}

}

I called getWindow from this class:

public class LoginState extends GameState {

private GameStateManager gsm;

public LoginState(GameStateManager gsm) {

    this.gsm = gsm;

}

private JTextField username;
private JTextField password;

public void init() {

    username = new JTextField(25);

    username.setVisible(true);
    username.setBounds(20, 20, 50, 50);

    Main.getWindow().add(username);

}

public void draw(Graphics2D g) {

    g.setColor(Color.gray);
    //g.fillRect(0, 0, Data.getIntegerValue("ScreenWidth"), Data.getIntegerValue("ScreenHeight"));

}

GameStateManager:

public class GameStateManager {

private ArrayList<GameState> gameStates;

public static final int LOGINSTATE = 0;
public static final int MENUSTATE = 1;
public static final int PLAYSTATE = 2;

private static int currentState;

public GameStateManager() {

    gameStates = new ArrayList<GameState>();

    currentState = LOGINSTATE;

    gameStates.add(new LoginState(this));
    gameStates.add(new MenuState(this));
    gameStates.add(new PlayState(this));

    gameStates.get(currentState).init();

}

Please help.

5
  • 3
    1) Where are you calling getWindow()? I don't see this being called anywhere. 2) What's with the static fields and methods? Commented Jan 20, 2016 at 19:40
  • ... but not quite enough as you don't show where the LoginWindow class is being constructed, i.e., where you call new LoginWindow(...);. Commented Jan 20, 2016 at 19:51
  • Added more info again Commented Jan 20, 2016 at 20:11
  • Chit -- It's nothing more than the order of calls you're making. Simply swap the two lines. Commented Jan 20, 2016 at 20:14
  • in short, don't do this, static is not an appropriate mechanism for cross object communication, instead, you should be pass the information that these classes need to each class, probably using some kind of data model Commented Jan 20, 2016 at 23:15

2 Answers 2

1

Thanks for the update, but... you still haven't shown where LoginWindow is being initialized.

A guess -- you're program is starting from a different main method from the one you're showing, and so the main method which creates and assigns your JFrame to the static window field is never called. I suggest that you avoid using static methods and fields in this way, that depend on a main method to initialize. Java is an OOP language -- so make your code OOP compliant and create needed objects within code guaranteed to be called, and then assign them to non-static fields.

edit: simply swap the two lines:

GameEngine game = new GameEngine();
window = new JFrame();

to

window = new JFrame();
GameEngine game = new GameEngine();
Sign up to request clarification or add additional context in comments.

Comments

0

Your JFrame gets initialized in the main method of Main. You are better off using a static initialization block instead.

static {
    window = new JFrame();

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setTitle(title + Version.newVersion());
    window.setResizable(false);
    window.add(game);
    window.setSize(1000, 720);
    window.setLocationRelativeTo(null);
    window.setVisible(true);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.