如何异步触发JProgressBar?

How to asynchronous trigger JProgressBar?

我在 JPanel 中有一个 JButton(swing),如果按下它,我将在其 [=13] 中的列表上执行 for 循环任务=].在这样做的同时,我需要更新 JProgressBar

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

现在源代码对我来说不可用,因为我完全更改了它并尝试将 Eclipse SWT 用于 JProgressBar 当触发 Swing JButton 时,它变得混乱。

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

我正在使用 JOptionPane 触发 JPanel

您需要在 EDT 的单独线程中完成冗长的 运行 工作并更新进度条值。大多数时候 SwingWorker 是一个很好的方法。因此,在该按钮的 ActionListener 中,您应该将长 运行 线程与 EDT 分开。你可以用 bare Thread 来做到这一点,但是 Workers 和特别是 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);
            }
        });
    }
}

希望这会有所帮助。

Asynchronously 使用 SwingWorker 处理 JProgressBar 进度,详细使用两个 Swing JButton btnStart and btnStop.

我们在这里获取源代码-

package com.practice;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class ProgressExample {

    private static JFrame frame;
    private static JButton btnStart;
    private static JButton btnStop;
    private static JProgressBar progress;
    private static Integer currValue;
    private static boolean swingWorkerHelper;
    private static SwingWorker<Integer, Void> swingWorker;

    public static void main(String[] args) {
        // Scheduling Swing app for the event dispatch thread(EDT) Asynchronously
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                runSwingAsynchronousApp();
            }
        });
    }

    private static void runSwingAsynchronousApp() {
        currValue = new Integer(0);

        btnStart = new JButton("Start");
        btnStop = new JButton("Stop");

        progress = new JProgressBar();
        progress.setMinimum(0);
        progress.setMaximum(100);
        progress.setStringPainted(true);

        btnStart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {

                if (btnStart.getText().equals("Pause")) {
                    // interrupting swingWorker method doInBackground() implicitly safely.
                    swingWorkerHelper = false;
                    btnStart.setText("Resume");
                } else {
                    if (btnStart.getText().equals("Start") || btnStart.getText().equals("Resume"))
                        btnStart.setText("Pause");

                    showProgress();
                }
            }
        });

        btnStop.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                // checking swingWorker Object is initialized or not
                if (swingWorker != null) {
                    // checking is swingWorker doing process in background or not
                    if (swingWorker.getState() == SwingWorker.StateValue.STARTED) {
                        btnStart.setText("Start");
                        // interrupting swingWorker method doInBackground() explicitly
                        swingWorker.cancel(true);
                        currValue = new Integer(0);
                    }
                }
            }
        });

        frame = new JFrame();
        frame.setTitle("Asynchronously trigger JProgressBar");
        frame.getContentPane().setLayout(new GridLayout(3, 2));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(400, 250, 400, 300);

        frame.getContentPane().add(btnStart);
        frame.getContentPane().add(btnStop);
        frame.getContentPane().add(progress);

        frame.setVisible(true);
    }

    private static void showProgress() {
        swingWorker = new SwingWorker<Integer, Void>() {
            @Override
            protected Integer doInBackground() throws Exception {

                if (!swingWorkerHelper)
                    swingWorkerHelper = true;

                while (currValue < progress.getMaximum() && swingWorkerHelper) {
                    try {
                        progress.setValue(++currValue);

                        if (isCancelled())
                            return currValue;

                        Thread.sleep(70);
                    } catch (InterruptedException iex) {
                        swingWorkerHelper = false;
                        System.out.println("Stop Button interrupted SwingWorker process...");
                    }
                }
                return currValue;
            }

            @Override
            public void done() {
                System.out.printf("Progress ends with value %s " + 
                (isCancelled() ? "with" : "without") + " interruption.\n", currValue);
                if (currValue >= progress.getMaximum()) {
                    btnStart.setText("Start");
                    currValue = new Integer(0);
                }
            }
        };
        swingWorker.execute();
    }

}

希望对您有所帮助。