我有一个 Swing 应用程序,它存储对象列表。当用户点击按钮时,

我想对列表中的每个对象执行两个操作,然后完成后在 JPanel 中绘制结果图。我一直在尝试使用 SwingWorker、Callable 和 Runnable 来进行处理,但无论我做什么,在处理列表时(可能需要几分钟,因为它是 IO 绑定的),GUI 都会被锁定。

我有一种感觉,这可能是我调用线程或其他东西的方式,或者可能与绘图函数有关?这不是线程,因为它非常快。

我也必须按顺序执行两个处理阶段,那么确保第二个处理阶段等待第一个处理阶段的最佳方法是什么?我用过 join(),然后

while(x.isAlive())  
{  
        Thread.sleep(1000);  
}

试图确保这一点,但我担心这也可能是我的问题的原因。

我一直在到处寻找一些指示,但由于我找不到任何指示,所以我确信我在这里做了一些愚蠢的事情。

有帮助吗?

解决方案

问题是,您的长时间运行的任务正在阻塞保持 GUI 响应的线程。

您需要做的是将长时间运行的任务放在另一个线程上。

执行此操作的一些常见方法是使用计时器或 SwingWorker.

Java教程 在他们的并发课上有很多关于这些事情的信息。

为了确保第一个任务在第二个任务之前完成,只需将它们放在同一个线程上即可。这样您就不必担心保持两个不同线程的时间正确。

以下是针对您的案例的 SwingWorker 的示例实现:

public class YourTaskSwingWorkerSwingWorker extends SwingWorker<List<Object>, Void> {
    private List<Object> list
    public YourClassSwingWorker(List<Object> theOriginalList){
        list = theOriginalList;
    }

    @Override
    public List<Object> doInBackground() {
        // Do the first opperation on the list
        // Do the second opperation on the list

        return list;
    }

    @Override
    public void done() {
        // Update the GUI with the updated list.
    }
}

要使用此代码,当触发修改列表的事件时,创建一个新的 SwingWorker 并告诉它开始。

其他提示

您没有正确返回Swing线程。我知道你正在使用的可调用/运行的,但我猜你不这样做是正确的(虽然你没有张贴足够的代码肯定知道)。

的基本结构是:

swingMethod() { // Okay, this is a button callback, we now own the swing thread
    Thread t=new Thread(new ActuallyDoStuff());
    t.start();
}

public class ActuallyDoStuff() implements Runnable {
    public void run() {
        // this is where you actually do the work
    }
}

这是刚刚从我的头顶,但我猜,你要么不是做thread.start,并且不是直接调用run方法,或者你正在做别的事情在第一种方法是锁它(喜欢的Thread.join)。这些都不将腾出的Swing线程。第一种方法必须迅速返回,只要它想要的run()方法可以采用。

如果您是在第一种方法做的Thread.join,那么线程在返回到系统!

编辑:(第二编辑实际上) 我想和你谈谈实际感受的问题 - 你可能需要考虑更多的模型/视图/控制器系统方面。你正在写的代码是控制器(视图一般被认为是在屏幕上的组件 - 视图/控制器通常很紧密结合)

当您的控制器获取的情况下,它应该通过工作给您的模型。该视图然后出来的图片。它不会等待模式,它只是做了。

当你的模型就完成了,它需要再告诉控制器到别的做一些事情。它通过的调用方法之一。这将控制权返回给控制器,你去你的快乐的方式。如果你仔细想想这样,分开控制,强行通行来回不觉得如此庞大,它实际上是非常普遍的做这种方式。

这听起来像问题可能是你正在等待的线程从GUI线程内完成。您的GUI线程不应该等待这些线程,而不是你应该有工作线程调用GUI线程设置一个标志上的一些方法。当两个标志设置,那么,你知道,这两个线程完成,你可以做图形。

我真的不能说的摆动线程模型,但是:

  

我必须做的两个处理阶段,以便太多,所以什么是保证第二个已经等待第一个最好的方法是什么?

有关这种功能,我建议你创建两个工作线程,并嵌入一个JMS代理。通过传递消息到他们从读取JMS队列传递工作的两个线程。您的GUI线程是免费检查队列以确定工作时发生的事情,并表示在UI的发挥状态。

我的问题的解决方案是jjnguy和比尔·K公司的答案的混合物,所以非常感谢该球员。我需要这样的的SwingWorker内使用线程:

public class Worker extends SwingWorker<Void, Void>   
{  
    private List<Object> list;  
    public YourClassSwingWorker(List<Object> theOriginalList){  
        list = theOriginalList;  
    }

    @Override
    public List<Object> doInBackground() {
        Thread t = new Thread(new ProcessorThread(list));  
        t.start();
    }

    @Override
    public void done() {
        // draw graph on GUI
    }
}  
class ProcessorThread implements Runnable {  
    //do lots of IO stuff  
    Thread t2 = new Thread(new SecondProcess());
    t2.start();  
}

这确保所有的工作是由工作线程完成远离GUI,同时也确保了SwingWorker类本身没有做完所有的工作,这可能是一个问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top