防止在后台任务期间锁定Swing GUI

Sim*_*onw 11 java swing multithreading swingworker event-dispatch-thread

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

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

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

我必须按顺序完成两个处理阶段,那么确保第二个阶段在第一个阶段等待的最佳方法是什么?我已经使用了join(),然后

while(x.isAlive())  
{  
        Thread.sleep(1000);  
}
Run Code Online (Sandbox Code Playgroud)

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

我一直在寻找一些指针,但由于我找不到任何东西,我确信我在这里做了些蠢事.

jjn*_*guy 18

问题是,您的长时间运行任务阻止了保持GUI响应的线程.

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

一些常见的方法是使用Timers或a 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.
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Bil*_*l K 6

你没有正确地返回摆动螺纹.我意识到你正在使用可调用/可运行但我猜你做得不对(虽然你没有发布足够的代码来确定).

基本结构如下:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

这只是我的头脑,但我猜你要么不是在做thread.start而是直接调用run方法,要么在第一个锁定它的方法中做其他事情(喜欢thread.join).这些都不会释放挥杆线程.第一种方法必须快速返回,run()方法可以随意返回.

如果您在第一个方法中执行thread.join,则该线程不会返回给系统!

编辑:(实际上是第二次编辑)我想谈谈你实际感受到的问题 - 你可能想要更多地考虑模型/视图/控制器系统.您正在编写的代码是控制器(视图通常被认为是屏幕上的组件 - 视图/控制器通常非常紧密地绑定).

当您的控制器获取事件时,它应该将工作传递给您的模型.然后视图不在图片中.它不等待模型,它刚刚完成.

模型完成后,需要告诉控制器执行其他操作.它通过一种调用方法完成此操作.这会将控制权转移回控制器,然后继续你的快乐方式.如果以这种方式考虑它,分离控制并故意来回传递它并不会感觉太笨重,而且这样做实际上很常见.