繁体   English   中英

如何在另一个线程中与计算并行地重新绘制()我的JPanel?

[英]How can I repaint() my JPanel in parallel with computations / in another 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

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

我猜我不能简单地说:

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

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

很简单,使用SwingWorker SwingWorker具有发布长时间运行的结果并在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中的并发性

在EDT中绘画,在其他线程中完成工作。 EDT是用于处理GUI的工具-试图使其中涉及另一个线程肯定会搞砸。

因此,真正的问题是,如何将“工作者”线程中的值或数据结构传递回UI进行绘制?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM