u3l
u3l

Reputation: 3412

How can I repaint() my JPanel in parallel with computations / in another thread?

Okay so, I have an algorithm working as mentioned below, and I wanted to know how I could repaint in a separate thread instead of the Event Dispatch Thread:

Input an ArrayList of 2 Dimensional Point objects.
while(each point object has not been a starting point)
LOOP

   Arbitrarily choose a starting point
   Find the shortest path through all nodes
   Call repaint() on the JPanel that displays this path.

END LOOP

My question is, how do I set up another Thread so that every time a shortest path is calculated, it sends the path to the thread that repaints the JPanel? I want to do this because I feel like i'm wasting time repainting() and this could make the method much faster.

I'm guessing that I can't simply say:

new Thread() {
    void run() {
        myJPane.repaint();
    }
}.start()

...since that would create a new thread every single time. How do I logically do this?

Upvotes: 0

Views: 396

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347204

Simple, use a SwingWorker. A SwingWorker has methods for publishing results of long running operations and processing those results on the EDT.

So basically...

public class PathFinderWorker extends SwingWorker<Void, Path> {
    protected Void doInBackground() throws Exception {
        Input an ArrayList of 2 Dimensional Point objects.
        while(each point object has not been a starting point) 
        LOOP
            Arbitrarily choose a starting point
            Find the shortest path through all nodes
            publish(path);

        END LOOP
    }

    protected void process(List<Path> paths) {
        // Process the results as required...
    }
}

The funny thing about repaint is, by it's design, it's one of the few methods that is actually thread safe.

That is, repaint asks the RepaintManager to repaint a give area. The RepaintManager will, at some time in the near future, schedule a paint event onto the Event Queue, is is then processed by the Event Dispatching Thread...safely...

For more details, take a look at Concurrency in Swing

Upvotes: 4

Thomas W
Thomas W

Reputation: 14164

Paint in the EDT, do your work in the other thread. The EDT is the one that's meant to deal with the GUI -- trying to get another thread involved there is guaranteed to screw up.

So the real question is, how to pass a value or data-structure from the "worker" thread back to the UI for painting?

Probably the simplest data-structure I've seen recently for this was a chain of Nodes, each with a back-pointer to the previous Node. Since they're immutable this can safely be passed between threads for display.

Upvotes: 0

Related Questions