0

好的,我有一个如下所述的算法,我想知道如何在单独的线程而不是事件调度线程中重绘:

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

我的问题是,如何设置另一个线程,以便每次计算最短路径时,它将路径发送到重新绘制 JPanel 的线程?我想这样做是因为我觉得我在浪费时间 repainting() 并且这可以使该方法更快。

我猜我不能简单地说:

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

...因为那会每次都创建一个新线程。我如何在逻辑上做到这一点?

4

2 回答 2

4

很简单,使用SwingWorker. ASwingWorker具有发布长时间运行操作的结果并在 EDT 上处理这些结果的方法。

所以基本上...

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...
    }
}

有趣的repaint是,根据它的设计,它是为数不多的真正线程安全的方法之一。

也就是说,repaint要求RepaintManager重新绘制给定区域。将RepaintManager在不久的将来的某个时间将paint事件安排到事件队列中,然后由事件调度线程处理......安全......

有关更多详细信息,请查看Swing 中的并发

于 2013-09-09T10:29:32.850 回答
0

在 EDT 中绘画,在另一个线程中完成您的工作。EDT 是用来处理 GUI 的——试图让另一个线程参与其中肯定会搞砸。

所以真正的问题是,如何将值或数据结构从“工作”线程传回 UI 进行绘制?

可能我最近看到的最简单的数据结构是一个节点链,每个节点都有一个指向前一个节点的反向指针。由于它们是不可变的,因此可以安全地在线程之间传递以进行显示。

于 2013-09-09T10:09:22.713 回答