Search code examples
javaswingcomponentsevent-dispatch-thread

Not showing Swing component when running before or in the game loop


I'm actually trying to fix a problem with the component of JFrame that don't want to show up when I run my game loop (see the question after the code). I have reduced the code at the minimum possible for you to get what I mean fast:

Run.class

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Game game = new Game();
            game.loop();
        }
    });
}

Game.class

private Frame frame;
private HashMap<String,ActionListener> actions;
private HashMap<String,Image> ressources;

public Game() {
    this.setActions();
    this.setRessources();
    frame = new Frame(actions,ressources);
}
public void loop() {
    double FPS = 60;
    double UPS = 60;
    long initialTime = System.nanoTime();
    final double timeU = 1000000000 / UPS;
    final double timeF = 1000000000 / FPS;
    double deltaU = 0, deltaF = 0;
    int frames = 0, ticks = 0;
    long timer = System.currentTimeMillis();
    boolean running = true;
    boolean RENDER_TIME = false;

    while (running) {
        ...code for update, render, with a fps control
    }
}

Frame.class

public Frame(HashMap<String,ActionListener> actions, HashMap<String,Image> ressources) {

    this.setTitle(Constants.GAME_NAME);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(Constants.GAME_SIZE_X, Constants.GAME_SIZE_Y);
    this.setLayout(new FlowLayout());

    JButton myButton = new JButton("My Button");
    this.add(myButton);

    this.revalidate();
    this.repaint();
    this.setVisible(true);
}

It's not the complete code because I don't want to give a useless thing. So here, my problem is:

If I run this code, the button not going to show up in the frame. But if I comment game.loop() in the Run.class, the windows show the button. And I don't understand WHY?

I have been trying for a few days to figure it out. I need some help for this one. Alone I'm afraid I will not find out.


Solution

  • To avid blocking the Event Dispatching Thread by running a long process you can use swing Timer which can handle the "looping" for you :

    ActionListener animate = e -> {
        game.oneFrame();
        panel.repaint();  
    };
    timer = new Timer(50, animate); 
    timer.start(); 
    
    public void oneFrame(){
       //update what is needed for one "frame"
    }
    

    For more help post mcve.