How do I keep a Java frame from waiting?

I am writing a genetic algorithm that approximates an image using a polygon. After going through different generations, I would like to output the progress to a JFrame. However, it looks like the JFrame is waiting for GA in the loop to finish displaying something. I don't believe this is a problem as repainting, as it will end up displaying everything as soon as the while loop exits. I want the GUI to update dynamically even if the while loop is running.

Here is my code:

while (some conditions) {
    //do some other stuff
    gui.displayPolygon(best);
    gui.displayFitness(fitness);
    gui.setVisible(true);
}

public void displayPolygon(Polygon poly) {
    BufferedImage bpoly = ImageProcessor.createImageFromPoly(poly);
    ImageProcessor.displayImage(bpoly, polyPanel);
    this.setVisible(true);
}

public static void displayImage(BufferedImage bimg, JPanel panel) {
    panel.removeAll();
    panel.setBounds(0, 0, bimg.getWidth(), bimg.getHeight());
    JImagePanel innerPanel = new JImagePanel(bimg, 25, 25);
    panel.add(innerPanel);
    innerPanel.setLocation(25, 25);
    innerPanel.setVisible(true);
    panel.setVisible(true);
}

      

+2


a source to share


2 answers


I think your problem is that Java won't let you update the GUI from a thread other than the GUI thread itself. This causes grief for everyone at some point, but fortunately, a fairly handy workaround is provided.

The idea is to pass the code that performs the update to either Runnable

method SwingUtilities.invokeAndWait

or SwingUtilities.invokeLater

. Here's an example .

To run GA at maximum speed and use parallelism I think invokeLater

would be appropriate.




EDIT: Oh wait, camickr's solution will tell you you are doing something else: you are using GA on the GUI thread. Well, only one or the other can do that, calculate or display. So the true solution will combine both changes:

  • Run GA on a separate thread (you can run it on the thread used main()

    after the GUI instance is instantiated); and
  • Use invokeLater

    to push updates to the GUI thread (which calls the EDT or Thread Dispatch Thread).
+1


a source


However, it looks like the JFrame is waiting for the GA while loop to end to display something. I do not believe this is a problem how to repaint

Yes, if the loop code is executed on EDT, then the GUI cannot be redrawn until the loop completes. The loop code must run on its own thread, so it doesn't block EDT.



Read more in the Swing tutorial section on Concurrency .

+3


a source







All Articles