• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

使用JProgressBar运行方法

用户头像
it1352
帮助1

问题说明

我有一个名为CreateAccount的函数.我需要它来运行,还需要显示一个进度栏.当我单击按钮时,该方法将开始.我需要开始显示加载进度栏.方法完成后,进度条也应停在100.如果该方法有更多时间来完成工作,则进度条也需要缓慢加载.

I have a function called CreateAccount. I need it to run and also need to show a progress bar. When I click the button, the method will start. And I need to start showing loading progress bar. Once method is done progress bar also should stop at 100. If the method gets more time to do the job, progress bar also needs to load slowly.

我尝试使用以下代码,但未将进度条与该方法同步.那我该怎么办呢?

I tried using following code but it is not synchronizing progress bar with the method. So how can I do that?

这是我的代码:

private static int t = 0;

private void createAccountBtnActionPerformed(java.awt.event.ActionEvent evt) {                                                 
        progressBar.setValue(0);
        progressBar.setStringPainted(true);

        new Thread(new Runnable() {
            @Override
            public void run() {
                //CreateAccount();

                for (t = 0; t <= 100; t  ) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            CreateAccount();
                            progressBar.setValue(t);
                        }
                    });
                    try {
                        java.lang.Thread.sleep(100);
                    }
                    catch(InterruptedException e) { }
                }
            }
        }).start();
    }

有人可以帮助我吗?预先感谢.

Anybody can help me? Thanks in advance.

正确答案

#1

由于Swing具有单线程特性,因此您无法在事件调度线程的上下文中执行长时间运行或阻塞操作,也无法更新从事件调度线程的上下文之外访问用户界面.

Because of the single threaded nature of Swing, you can't perform long running or blocking operations from within the context of the Event Dispatching Thread, nor can you update the UI from outside the context of the Event Dispatching Thread.

有关更多详细信息,请参见 Swing中的并发.

See Concurrency in Swing for more details.

这两种事情您都需要照顾.问题是,这意味着后台线程可能会执行比UI上提供的更多的工作,而您无能为力.最好的选择就是简单地尝试尽可能使UI保持最新状态

Both these things you are taking care of. The problem is, this means that it's possible for the background thread to do more work than is been presented on the UI and there's nothing you can do about. The the best bet is simply trying too keep the UI up-to-date as much as possible

一个更好的解决方案可能是使用SwingWorker,它旨在使UI的更新更加容易.有关更多详细信息,请参见工作线程和SwingWorker .

A possible better solution might be to use a SwingWorker, which is designed to make updating the UI easier. See Worker Threads and SwingWorker for more details.

以下示例显示了一个进度条,它将运行10秒钟,每次更新之间最多有500毫秒的随机延迟.然后根据剩余时间更新进度条.

The following example shows a progress bar which will run for 10 seconds with a random delay of up to 500 milliseconds between each update. The progress bar is then update based on the amount of time remaining.

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.time.Duration;
import java.time.Instant;
import java.util.Random;
import javax.swing.JButton;
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 final class Test {

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

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

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

    public class TestPane extends JPanel {

        private JProgressBar pb;
        private JButton btn;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            btn = new JButton("Go");
            pb = new JProgressBar();

            add(btn, gbc);
            add(pb, gbc);

            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btn.setEnabled(false);
                    makeItProgress();
                }
            });
        }

        protected void makeItProgress() {
            SwingWorker<Double, Double> worker = new SwingWorker<Double, Double>() {
                @Override
                protected Double doInBackground() throws Exception {
                    Duration duration = Duration.ofSeconds(10);
                    Instant startTime = Instant.now();
                    Duration runningTime = Duration.ZERO;
                    Random rnd = new Random();
                    setProgress(0);
                    do {
                        Thread.sleep(rnd.nextInt(500));
                        Instant now = Instant.now();
                        runningTime = Duration.between(startTime, now);

                        double progress = (double) runningTime.toMillis() / (double) duration.toMillis();
                        setProgress((int) (progress * 100));
                    } while (duration.compareTo(runningTime) >= 0);
                    setProgress(100);
                    return 1.0;
                }
            };
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    SwingWorker worker = (SwingWorker) evt.getSource();
                    if (evt.getPropertyName().equals("progress")) {
                        int value = (int) evt.getNewValue();
                        pb.setValue(value);
                    } else if (evt.getPropertyName().equals("state") && worker.getState() == SwingWorker.StateValue.DONE) {
                        pb.setValue(100);
                        btn.setEnabled(true);
                    }
                }
            });
            worker.execute();
        }

    }

}

此示例的要点是,将进度和工作混合到单个操作中(SwingWorkerdoInBackground方法),因此它们之间的关系更为紧密.然后SwingWoker通知PropertyChangeListener更新,它可以在事件分派线程上安全地对其做出反应

The point of this example is, the progress and the work are mixed into a single operation (the doInBackground method of the SwingWorker) so they are more closely related. The SwingWoker then notifies the PropertyChangeListener of updates, to which it can react to safely on the Event Dispatching Thread

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhcfhggf
系列文章
更多 icon
同类精品
更多 icon
继续加载