java - 如何使用 Swing Timer 延迟进度条的加载

标签 java swing timer progress-bar sleep

我需要找到一种使用带进度条的 Swing Timer 的方法。我尝试使用 Thread.sleep(),但是当我使用它时应用程序崩溃了。有什么方法可以使用 Swing Timer 而不是 Sleep()?

public void piiEros(int dist)
{
    Pii pii = new Pii();
    pii.setVisible(true);
    for(int pc = 0;100 > pc; pc++)
    {
        try {
            Thread.sleep(dist/100);
        } catch (InterruptedException ex) {
            Logger.getLogger(Trav.class.getName()).log(Level.SEVERE, null, ex);
        }
        pii.pg.setValue(pc);
    }
    pii.dispose();
    o.Eros();
}

注意:Pii 是一个带有进度条的类。 Dist 是它加载的速度。 Trav 是方法所在的类。Pc 代表 %,完成了多少显示在栏上。 o.Eros 打开另一个 GUI。

最佳答案

使用 SwingWorker 可能更容易(从长远来看)。它提供了许多有用的方法来更新 UI(从事件调度线程的上下文),同时允许在后台继续执行...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestSwingWorker02 {

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

    public TestSwingWorker02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            JProgressBar pb = new JProgressBar();
            add(pb);

            new ProgressWorker(pb, 40).execute();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class ProgressWorker extends SwingWorker<Void, Integer> {

        private int delay;
        private JProgressBar pb;

        public ProgressWorker(JProgressBar progressBar, int delay) {
            this.pb = progressBar;
            this.delay = delay;
        }

        @Override
        protected void process(List<Integer> chunks) {
            // Back in the EDT...
            pb.setValue(chunks.get(chunks.size() - 1)); // only care about the last one...
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (int index = 0; index < 100; index++) {
                publish(index);
                Thread.sleep(delay);
            }
            return null;
        }

        @Override
        protected void done() {
            // Back in the EDT...
            //pii.dispose();
            //o.Eros();
        }

    }

}

SwingWorker 允许您分离逻辑。在doInBackground方法中你可以专注于需要在EDT之外运行的那部分代码,你可以publish更新回EDT并process他们分开。全部完成后,您可以根据需要进行清理。

SwingWorker 还提供进度监控功能,因此,在您的情况下,您不必使用 publish/process API 的一部分(如果您不想)。这将允许您将 PropertyChangeListener 附加到 worker 而无需向其公开进度条。 (但我做了例子)

public class ProgressWorker extends SwingWorker<Void, Integer> {

    private int delay;
    private JProgressBar pb;

    public ProgressWorker(JProgressBar progressBar, int delay) {
        this.pb = progressBar;
        this.delay = delay;
        // You can use a property change listener to monitor progress updates...
        addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                    pb.setValue((Integer)evt.getNewValue());
                }
            }

        });
    }

    @Override
    protected Void doInBackground() throws Exception {
        for (int index = 0; index < 100; index++) {
            setProgress(index);
            Thread.sleep(delay);
        }
        return null;
    }

    @Override
    protected void done() {
        // Back in the EDT...
        //pii.dispose();
        //o.Eros();
    }

}

关于java - 如何使用 Swing Timer 延迟进度条的加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15668715/

相关文章:

javascript - 数据库获取后便士拍卖计时器更新

ios - 为什么不早点调用自定义CALayer的draw方法呢?

java - 如何通过 Xpath 查询 Selenium 中的 HTML 元素?

java - JDIALOG 没有看到其他类

c# - 理解 wsdl 服务的 java 类

java - 如何将JDialog置于顶部

java - 从 jframe 传递一个值并将其使用到另一个 jframe

c# 在特定时间在标签中显示文本

java - Java 中的 3d 游戏编程

java - Java Applet 中的 ClassNotFoundException