Java Swing JFrame launch another JFrame for game

652 views Asked by At

I am developping a little game using Java. I have a main JFrame for my application that can create another Window (the game window) by clicking on a JButton. I have already teste my game window alone and everything is ok.

Here is my game window constructor:

public GameWindow(final GameController controller)
{
    super("Boulder Dash Game");

    this.controller = controller;
    this.controller.registerObserver(getCurrentFrame()); 
    this.gamePanel = new GamePanel(controller);

    this.frameWidth = controller.getColumns() * 16;
    this.frameHeight = controller.getRows() * 16 + 76;

    getContentPane().add(gamePanel, BorderLayout.CENTER);

    setSize(frameWidth, frameHeight);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    controller.startGame();
}

The controller.startGame() method start the game loop. The game loop work fine when I start this window directly from my main.

Now, I want to launch this GameWindow frame from my main frame. Here is a code from my main frame:

playButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(final @Nullable ActionEvent e)
    {
        String selectedItem = (String) levelsComboBox.getSelectedItem();
        assert selectedItem != null;
        controller.lauchGame(selectedItem);
    }
});

The controller.launchGame(String selectedItem) is a method used to load a game level and to start the gamewindow. Here is the code

public void lauchGame(final String levelQueried)
{
    assert levelQueried != null;
    Level level = LevelRepository.load(levelQueried);
    assert level != null;
    GameController controller = new GameController(model);
    GameWindow view = new GameWindow(controller);
}

My problem is that when I start the GameWindow from the other JFrame, I don't have any elements on it. If I don't start the game loop in the constructor, my gamewindows seems to be initialised correctly (content, EXIT ON CLOSE action...). But when I start the gameloop, I juste have an empty JFrame (correctly sized) with no content.. And when I try to quit the frame, I can't...

here is the code of my game loop:

public void start() throws InterruptedException // Game loop method
{
    boolean updateGame = true;
    while ( !isFinish() ) {
        // We update the elements only 1 round of 2
        if ( updateGame ) {
            updateExitState();
            getPlayField().updateMoovableEntities();
            updateGame = false;
        } else {
            updateGame = true;
        }
        Thread.sleep(100);
        // Animate the sprite at every round
        setChanged(); 
        notifyObservers(); // inform that a repaint is necessary
    }
    LOGGER.debug("The game loop for the current level is now finished.");
}

On the console, I can see that the gameloop is playing and the update method is correctly called... But the paintComponent is never called... so there is nothing on my frame !

I don't have any Idea about the problem... Can someone help me please ?

edit:

Thank you for you answers. I have modified the constructor of my GameWindow using

javax.swing.SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run()
    {
        controller.startGame();
    }
});

It is a bit better, now my frame is correctly initialised. But now there is another problem, the listeners are no longer available... I can not interact at all with my frame (can't exit, or do any other action...). What's wrong ?

1

There are 1 answers

1
Hovercraft Full Of Eels On BEST ANSWER

You're completely freezing the Swing event thread (the EDT or event dispatch thread) by running a while (true) loop on it. Don't do that. Instead either run your while loop in a background thread, or else use a Swing Timer to drive your game loop. Read Concurrency in Swing for more on this. Also, please read The Use of Multiple JFrames question on this site.

Note that when you (incorrectly) started your GUI and your game loop in the main method, your game loop ran in the main thread and not the Swing event thread, and so in this situation your game worked, but it's not a good solution since the main GUI is also started off of the Swing event thread, and this can lead to intermittent hard to debug threading errors.