小编典典

如何异步触发JProgressBar?

java

我在中有一个JButtonswingJPanel,如果按下该按钮,我将在for循环中对其列表中的列表执行任务EDT thread。这样做时,我需要更新JProgressBar

问题是,当我按下JButton时,该任务是在事件调度线程(EDT)中执行的。因此,我无法更新JProgressBar在主线程或UI线程中触发的事件。

现在,源代码对我不可用,因为我完全更改了源代码,并尝试使用Eclipse SWT
触发JProgressBarSwing时JButton,它变得混乱。

现在我得到了invalid thread access错误,因为Display对象在单独的UI线程中运行。一次只显示Swing
JPanel或Eclipse SWT Shell

我正在触发JPanel使用JOptionPane


阅读 242

收藏
2020-11-26

共1个答案

小编典典

您需要长时间运行并在之外的单独Thread中更新进度栏值EDT。在大多数情况下,这SwingWorker是一个很好的方法。因此,在ActionListener该按钮中,应将长时间运行的线程与EDT分开。您可以赤手空拳来完成此任务,Thread并且专门SwingWorker针对此类情况设计:

package graphics;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class GraphicDev extends JFrame{

    private static final long serialVersionUID = 679207429168581441L;
    //
    private static final int FRAME_WIDTH = 300;
    private static final int FRAME_HEIGHT = 100;

    private int percent;
    private JProgressBar progress;

    public GraphicDev() {
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(dim.width/2-FRAME_WIDTH/2, dim.height/2-FRAME_HEIGHT/2, FRAME_WIDTH, FRAME_HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //
        setLayout(new FlowLayout());
        //
        progress = new JProgressBar(0, 100);
        progress.setStringPainted(true);
        //
        JButton actButton = new JButton("Start!");
        actButton.addActionListener(new ActionListener() {          
            @Override
            public void actionPerformed(ActionEvent e) {
                new SwingWorker<Void, Void>() {
                    @Override
                    protected Void doInBackground() throws Exception {
                        for (long i = 0; i < 10000000000000L; i++) {
                            System.out.println(i);
                            if(i%200000 == 0){
                                progress.setValue(percent++);
                            }
                            if(percent >= 100){
                                break;
                            }
                        }
                        return null;
                    }

                    @Override
                    protected void done() {
                        JOptionPane.showMessageDialog(GraphicDev.this, "Done!");
                    }

                }.execute();    
            }
        });
        //
        add(actButton);
        add(progress);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                GraphicDev g = new GraphicDev();
                g.setVisible(true);
            }
        });
    }
}

希望这会有所帮助。

2020-11-26