Java SwingGUI下的长流程:SwingWorker的替代方案?

Java SwingGUI下的长流程:SwingWorker的替代方案?,java,swing,swingworker,Java,Swing,Swingworker,下面的MCVE演示了运行长流程的Swinggui。长流程在SwingWorker中运行,因此不会阻止(冻结)GUI: 导入java.awt.BorderLayout; 导入java.awt.Color; 导入java.awt.FlowLayout; 导入java.awt.event.ActionEvent; 导入java.awt.event.ActionListener; 导入javax.swing.JButton; 导入javax.swing.JDialog; 导入javax.swing.JF

下面的MCVE演示了运行长流程的
Swing
gui。长流程在
SwingWorker
中运行,因此不会阻止(冻结)GUI:

导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.FlowLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.JButton;
导入javax.swing.JDialog;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingWorker;
公共类DiagA扩展JDialog{
私有框架b框架;
专用按钮btn;
公共诊断(){
超级();
设置标题(“主框架”);
设置大小(200150);
设置位置(400400);
btn=新的JButton(“显示帧B”);
btn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
show2ndFrame();
}
});
添加(btn,BorderLayout.NORTH);
setVisible(真);
}
void show2ndFrame(){
if(frame==null){
frame=新FrameB();
btn.setText(“退出”);
}否则{
系统出口(0);
}
销钉();
}
私房{
SwingWorker sw=新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
试一试{

对于(int i=1;i在
线程中的每个进程上
,但只需确保使用
调用器(..)
计划任何GUI更新。请注意,
SwingWorker
旨在作为API,使
线程
/
调用器(..)
不那么麻烦!请记住,
doInBackground
是在工作线程中执行的,而不是在UI线程(事件调度程序线程)中执行的。因此,您不应该调用
frame.update()
在该方法中。工作线程应该使用
publish
方法,您应该重写
进程
,以更新ui组件。@rene-Link感谢您的评论。在实际程序中,我使用
发布
进程
获取
(如果我只需要最终返回值)。我试图尽可能地保持MCVE。你能详细说明一下你所说的繁琐是什么意思吗?你可以像这样管理多个工作人员。在
线程中运行每个进程,但只需确保使用
调用器(..)安排任何GUI更新即可
。请注意,
SwingWorker
本打算作为API,使
线程
/
调用器(…)
更简单!请记住
doInBackground
是在工作线程中执行的,而不是在UI线程(事件调度程序线程)中执行的。因此,您不应该调用
frame.update()
在该方法中。工作线程应该使用
publish
方法,您应该重写
进程
,以更新ui组件。@rene-Link感谢您的评论。在实际程序中,我使用
发布
进程
获取
(如果我只需要最终返回值).我试着尽可能地保留MCVE。你能详细说明一下你所说的笨重是什么意思吗?你可以像这样管理多个工人。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;

public class DiagA extends JDialog  {

    private FrameB frame;
    private JButton btn;

    public  DiagA() {

        super();
        setTitle("main frame");
        setSize(200, 150);
        setLocation(400,400);

        btn = new JButton("Show Frame B");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {

                show2ndFrame();
            }
        });
        add(btn, BorderLayout.NORTH);
        setVisible(true);
    }

    void show2ndFrame() {

        if(frame == null) {

            frame = new FrameB();
            btn.setText("Exit");

        }else {

            System.exit(0);
        }

        doWork();
    }

    private void doWork() {

        SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {

                try {

                    for(int i = 1 ; i<=100 ; i++) {
                        //represents a long process
                        Thread.sleep(100);
                        frame.update(i);
                    }

                } catch (InterruptedException ex) {}
                return null;
            }
        };
        sw.execute();
    }

    public static void main(String[] args) {
        new  DiagA();
    }
}

class FrameB extends JFrame  {

   JLabel label;

    public  FrameB() {

        super();
        setTitle("2nd frame");
        setSize(150, 100);
        setLocation(600,420);
        setLayout(new FlowLayout(FlowLayout.CENTER));
        getContentPane().setBackground(Color.YELLOW);
        label = new JLabel("0");
        add(label);
        setVisible(true);
    }

    void update(int progress) {

        label.setText(String.valueOf(progress));
    }
}