Martin
Martin

Reputation: 277

Problems with multiple JFrames

I've been coding a traffic simulation, and have structured the code as follows:

In my main function of the project class, I run only a short bit of code:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
    InputGUI inputgui = new InputGUI();
    inputgui.setVisible(true);
        }
    });

where InputGUI() is a class that calls up a JFrame where I pass parameters to the simulation using textfields. There is a JButton that I click that calls the function runsimulation() in its ActionPerformed event handler.

In this runsimulation, I run the actual simulation, but also open a new JFrame that visually models what the simulation is doing. The code looks as follows:

RoadNetwork roadnetwork = new RoadNetwork();
    roadnetwork.setVisible(true);
    JFrame frame = new JFrame();
    frame.add(roadnetwork);
    frame.setSize(1250, 750);
    frame.setVisible(true);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 

where RoadNetwork is a class extending JPanel that handles the vizualisation by overriding paintComponent. Then, in my iterative for loop in the runsimulation() function, I call

roadnetwork.repaint();

which used to work when all my code was only in the main function and I hadn't written and used the the GUI class yet.

However, now the JFrame opens up when I hit the JButton, but the frame doesn't update until the simulation ends. When it ends, the last state of the simulation is drawn as it should be, but before that I see only a grey area where the simulation normally happens, and a black border around that in the window.

What am I doing wrong?

Upvotes: 1

Views: 179

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285460

You've likely got a Swing threading issue. When you previously ran the code from the main thread, the long-running bit of code ran on the main thread and not in the Swing thread. Now that your simulation is being started in the Swing thread, the problems are showing since your long-running code is now running in the Swing Event Dispatch Thread or EDT, hogging and effectively freezing this thread and preventing all GUI drawing from occurring since this is the thread that is responsible for all Swing painting and user interaction.

Suggestions:

  • Use a SwingWorker or other background thread for all long-running code.
  • Make sure to update Swing objects on the Swing thread only, the EDT. The SwingWorker makes this easier to do.
  • Don't have any of your code logic in your painting methods whatsoever. The paintComponent method should be for drawing and drawing only.

For details on Swing threading issues (and as Keven Workman suggests), please have a look at the Concurrency in Swing Tutorial. Also, if these suggestions don't help you, consider telling and showing (code) us more.

Upvotes: 2

Related Questions