0

I have a problem regarding invokeLater method - I am not sure if I understand correctly where I use should it. Take a look at the following code:

  public class Jumper implements Runnable {
    private Panel panel;
    private boolean running; 

    public Jumper() {
        LevelConfiguration levelConfiguration = new LevelConfiguration();// loads level configuration from the file
        Character character = new Character(levelConfiguration);
        Board board = new Board(levelConfiguration);

        Frame frame = new Frame();                                       // creates application's window
        panel = new Panel(levelConfiguration, character, board);         // creates panel and draw board and character
        frame.addComponent(panel.getPanel(), BorderLayout.SOUTH);
        InformationPanel infoText = new InformationPanel();              // creates JTextField...
        frame.addComponent(infoText.getTextField(), BorderLayout.NORTH); // ... and sets it above JPanel
        frame.packFrame();                                               // pack and set visibility

        start();
    }

    @Override
    public void run() {
        // do stuff and call render() method once in a while
        render();
   }

   private void render(){
        panel.getPanel().repaint();
    }

    private void start() {
        if (running) {
            return;
        }
        running = true;
        new Thread(this, "JumperMain-Thread").start();
    }
}

And Panel class:

 public class Panel {
    private JPanel panel;

    public Panel(final LevelConfiguration levelConfiguration, final Character character, final Board board) {
        int gamePanelWidth = levelConfiguration.getGamePanelWidth();
        int gamePanelHeight = levelConfiguration.getGamePanelHeight();

        panel = new JPanel(true)
        {
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                board.drawBoard(g);
                character.drawCharacter(g);
            }
        };
        panel.setLayout(new FlowLayout());
        panel.setPreferredSize(new Dimension(gamePanelWidth, gamePanelHeight));
        panel.setBorder(BorderFactory.createEmptyBorder());
    }

I think that the proper way of using invokeLater in this code would be

  1. from line Frame frame = … to frame.packFrame();
  2. render() since it calls repaint()
  3. last 3 lines in Panel class

Can someone confirm whether I think right or wrong?

SantaXL
  • 618
  • 8
  • 19
  • 1
    1) use it when creating the GUI in the first place, 2) any time you are making Swing calls from a thread that is not the Swing event thread (exception for calling `repaint()`. 3) I would get rid of the background threading and the while loop, and would instead use a Swing Timer, since with this tool, all the code in the game loop is automatically called on the event thread, and you don't have to worry so much about this sort of stuff. – Hovercraft Full Of Eels Dec 02 '17 at 20:44
  • [Other similar questions](https://www.google.com/search?q=site%3Astackoverflow.com+java+swing+when+must+use+invokeLater) – Hovercraft Full Of Eels Dec 02 '17 at 20:45

0 Answers0