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

Java 如何在另一个线程中与计算并行地重新绘制()我的JPanel?,java,multithreading,swing,jpanel,repaint,Java,Multithreading,Swing,Jpanel,Repaint,好的,我有一个如下所述的算法,我想知道如何在单独的线程中重新绘制,而不是在事件调度线程中重新绘制: 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 Ca

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

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的线程?我之所以想这样做,是因为我觉得重新绘制()是在浪费时间,这可以使方法更快

我猜我不能简单地说:

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

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

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

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


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

在EDT中绘制,在另一个线程中执行您的工作。EDT是用来处理GUI的——试图让另一个线程参与其中肯定会出错

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


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

简单,使用
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...
    }
}
公共类PathFinderWorker扩展SwingWorker{
受保护的Void doInBackground()引发异常{
输入二维点对象的阵列列表。
while(每个点对象都不是起点)
环
任意选择起点
找到通过所有节点的最短路径
发布(路径);
端环
}
受保护的无效进程(列表路径){
//按要求处理结果。。。
}
}
repaint
的有趣之处在于,从设计上看,它是为数不多的真正线程安全的方法之一

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


有关更多详细信息,请查看简单,使用
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...
    }
}
公共类PathFinderWorker扩展SwingWorker{
受保护的Void doInBackground()引发异常{
输入二维点对象的阵列列表。
while(每个点对象都不是起点)
环
任意选择起点
找到通过所有节点的最短路径
发布(路径);
端环
}
受保护的无效进程(列表路径){
//按要求处理结果。。。
}
}
repaint
的有趣之处在于,从设计上看,它是为数不多的真正线程安全的方法之一

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


有关更多详细信息,请查看

为什么使用
new-Thread(){
而不是
Swing-Timer
,是否有类似于
OpenGL
的东西对不起,我不明白如何在这里使用Swing-Timer…请使用
new-Thread()说明原因{
而不是
Swing Timer
,是否有类似于as
OpenGL
的东西对不起,我不明白如何在这里使用Swing Timer…好的,那么在完成所有工作的类中-我现在明白必须在单独的线程中-我如何调用repaint()这样它就可以在EDT中重新绘制,而不是在单独的线程中重新绘制?我不确定我是否完全理解您的最后一段(对不起,我对并发和线程非常陌生)您可以添加一个链接来解释吗?@Trust就其性质而言,
repaint
总是将实际重新绘制安排回EDT。
repaint
simple要求
RepaintManager
绘制一个区域。
RepaintManager
然后将绘制事件安排到事件队列中,该事件队列由EDT处理……因此可以简单地调用repaint()吗从EDT以外的线程在面板上执行操作,而不做任何其他操作?有那么简单吗?@trust
repaint
,是的。但是,请注意,如果UI依赖于线程正在更改的任何内容,则需要同步这些内容…好的…我猜这意味着我必须阅读同步内容。好的,那么在完成所有工作的类中-w我现在理解它必须在一个单独的线程中-我如何调用repaint()以便它在EDT中而不是在单独的线程中重新绘制?我不确定我是否完全理解你的最后一段(对不起,我对并发和线程非常陌生)您可以添加一个链接来解释吗?@Trust就其性质而言,
repaint
总是将实际重新绘制的内容安排回EDT。
repaint
simple要求
RepaintManager
绘制一个区域。
RepaintManag