且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SwingWorker 进度条

更新时间:2022-10-28 12:03:16

几件事:

  1. SwingWorker 有四个规则要遵循.可以参考这个图:.
  1. There are four rules to follow with SwingWorker. You can refer to this diagram: .

所以,这段代码:

@Override
public String doInBackground() {
    //download here
    label.setText("test");

违反了该规则.您的 label.setText() 应该移到构造函数中.

violates that rule. Your label.setText() should be moved to the constructor.

  1. 要将更新"发送到 Swing 组件(如进度条),您需要使用 process() 方法,您可以从内部使用 publish() 调用该方法你的 doInBackground().您的 second SwingWorker 参数反映了您要传递的值的类型.我附上了两个 SSCCE.一个传递一个 Integerprocess() 方法,另一个传递一个 String.应该让您了解正在发生的事情.
  1. To send "updates" to Swing components (like your progress bar) you want to use the process() method, which you invoke using publish() from inside your doInBackground(). Your second SwingWorker parameter reflects the type of value you want to pass. I've attached two SSCCEs. One passes an Integer to the process() method, the other passes a String. Should give you an idea of what's going on.

使用 Integer 的 SSCCE:

SSCCE using Integer:

import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/**
 *
 * @author Ryan
 */
public class Test {

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                go();
            }
        });
    }

    public static void go() {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Loading...");
        JProgressBar jpb = new JProgressBar();
        jpb.setIndeterminate(false);
        int max = 1000;
        jpb.setMaximum(max);
        panel.add(label);
        panel.add(jpb);
        frame.add(panel);
        frame.pack();
        frame.setSize(200,90);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Task_IntegerUpdate(jpb, max, label).execute();

    }

    static class Task_IntegerUpdate extends SwingWorker<Void, Integer> {

        JProgressBar jpb;
        int max;
        JLabel label;
        public Task_IntegerUpdate(JProgressBar jpb, int max, JLabel label) {
            this.jpb = jpb;
            this.max = max;
            this.label = label;
        }

        @Override
        protected void process(List<Integer> chunks) {
            int i = chunks.get(chunks.size()-1);
            jpb.setValue(i); // The last value in this array is all we care about.
            System.out.println(i);
            label.setText("Loading " + i + " of " + max);
        }

        @Override
        protected Void doInBackground() throws Exception {
            for(int i = 0; i < max; i++) {
                Thread.sleep(10); // Illustrating long-running code.
                publish(i);
            }
            return null;
        }

        @Override
        protected void done() {
            try {
                get();
                JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }   
}

使用 String 的 SSCCE:

SSCCE using String:

import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/**
 *
 * @author Ryan
 */
public class Test2 {

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                go();
            }
        });
    }

    public static void go() {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel label = new JLabel("Loading...");
        JProgressBar jpb = new JProgressBar();
        jpb.setIndeterminate(true);
        panel.add(label);
        panel.add(jpb);
        frame.add(panel);
        frame.pack();
        frame.setSize(200,90);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Task_StringUpdate(label).execute();
    }

    static class Task_StringUpdate extends SwingWorker<Void, String> {

        JLabel jlabel;
        public Task_StringUpdate(JLabel jlabel) {
            this.jlabel = jlabel;
        }

        @Override
        protected void process(List<String> chunks) {
            jlabel.setText(chunks.get(chunks.size()-1)); // The last value in this array is all we care about.
            System.out.println(chunks.get(chunks.size()-1));
        }

        @Override
        protected Void doInBackground() throws Exception {

            publish("Loading Step 1...");
            Thread.sleep(1000);
            publish("Loading Step 2...");
            Thread.sleep(1000);
            publish("Loading Step 3...");
            Thread.sleep(1000);
            publish("Loading Step 4...");
            Thread.sleep(1000);

            return null;
        }

        @Override
        protected void done() {
            try {
                get();
                JOptionPane.showMessageDialog(jlabel.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}