简体   繁体   English

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

[英]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? 我的问题是,如何设置另一个线程,以便每次计算最短路径时,它将路径发送到重新绘制JPanel的线程? I want to do this because I feel like i'm wasting time repainting() and this could make the method much faster. 我想这样做是因为我觉得我在浪费时间repainting(),这会使该方法更快。

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? 我如何逻辑上做到这一点?

Simple, use a SwingWorker . 很简单,使用SwingWorker A SwingWorker has methods for publishing results of long running operations and processing those results on the EDT. SwingWorker具有发布长时间运行的结果并在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. 关于repaint的有趣之处在于,它的设计使其成为实际上是线程安全的少数几种方法之一。

That is, repaint asks the RepaintManager to repaint a give area. 也就是说, repaint要求RepaintManager重新绘制给定区域。 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... RepaintManager将在不久的将来的某个时间将paint事件安排到事件队列中,然后由事件调度线程进行安全处理...

For more details, take a look at Concurrency in Swing 有关更多详细信息,请查看Swing中的并发性

Paint in the EDT, do your work in the other thread. 在EDT中绘画,在其他线程中完成工作。 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. EDT是用于处理GUI的工具-试图使其中涉及另一个线程肯定会搞砸。

So the real question is, how to pass a value or data-structure from the "worker" thread back to the UI for painting? 因此,真正的问题是,如何将“工作者”线程中的值或数据结构传递回UI进行绘制?

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. 由于它们是不可变的,因此可以安全地在线程之间传递它们以进行显示。

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

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