从新线程更新 JProgressBar

发布于 2024-08-30 16:57:12 字数 938 浏览 11 评论 0原文

如何从另一个线程更新 JProgressBar.setValue(int) ? 我的第二个目标是用尽可能少的课程来完成它。

这是我现在的代码:

// Part of the main class....
pp.addActionListener(
        new ActionListener(){
            public void actionPerformed(ActionEvent event){
                new Thread(new Task(sd.getValue())).start(); 
            }
        });

public class Task implements Runnable {
    int val;
    public Task(int value){
        this.val = value;
    }

    @Override
    public void run() {
        for (int i = 0; i <= value; i++){ // Progressively increment variable i 
            pbar.setValue(i); // Set value 
            pbar.repaint(); // Refresh graphics 
            try{Thread.sleep(50);} // Sleep 50 milliseconds 
            catch (InterruptedException err){} 
        } 
    }
}

pp 是一个 JButton,单击 JButton 时启动新线程。

pbar 是 Main 类中的 JProgressBar 对象。

我怎样才能更新它的值?(进度)

上面的代码在run()中看不到pbar。

How can I update the JProgressBar.setValue(int) from another thread?
My secondary goal is do it in the least amount of classes possible.

Here is the code I have right now:

// Part of the main class....
pp.addActionListener(
        new ActionListener(){
            public void actionPerformed(ActionEvent event){
                new Thread(new Task(sd.getValue())).start(); 
            }
        });

public class Task implements Runnable {
    int val;
    public Task(int value){
        this.val = value;
    }

    @Override
    public void run() {
        for (int i = 0; i <= value; i++){ // Progressively increment variable i 
            pbar.setValue(i); // Set value 
            pbar.repaint(); // Refresh graphics 
            try{Thread.sleep(50);} // Sleep 50 milliseconds 
            catch (InterruptedException err){} 
        } 
    }
}

pp is a JButton and starts the new thread when the JButton is clicked.

pbar is the JProgressBar object from the Main class.

How can I update its value?(progress)

The code above in run() cannot see the pbar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千纸鹤 2024-09-06 16:57:17
  • 无需显式调用 pbra.repaint。
  • 更新 JProgressBar 应通过 GUI 调度线程完成。

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // Remember to make pbar final variable.
        pbar.setValue(i);
    }
});
  • There is need not to call pbra.repaint explicitly.
  • Update JProgressBar shall be done through GUI dispatch thread.

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // Remember to make pbar final variable.
        pbar.setValue(i);
    }
});
眼趣 2024-09-06 16:57:16

始终遵守 swing 的规则

一旦实现了 Swing 组件,所有可能影响或依赖于该组件状态的代码都应该在事件分派线程中执行。

您可以做的是创建一个观察者将更新你的进度条 - 例如
- 在这种情况下,您希望显示单击按钮时加载数据的进度。
DemoHelper 类实现 Observable 并在加载一定百分比的数据时向所有观察者发送更新。
进度条通过 public void update(Observable o, Object arg) { 无耻插件更新

class PopulateAction implements ActionListener, Observer {

    JTable tableToRefresh;
    JProgressBar progressBar;
    JButton sourceButton;
    DemoHelper helper;
    public PopulateAction(JTable tableToRefresh, JProgressBar progressBarToUpdate) {
        this.tableToRefresh = tableToRefresh;
        this.progressBar = progressBarToUpdate;
    }

    public void actionPerformed(ActionEvent e) {
        helper = DemoHelper.getDemoHelper();
        helper.addObserver(this);
        sourceButton = ((JButton) e.getSource());
        sourceButton.setEnabled(false);
        helper.insertData();
    }

    public void update(Observable o, Object arg) {
        progressBar.setValue(helper.getPercentage());
    }
}

:这来自 来自我的演示项目的源
欢迎浏览了解更多详情。

Always obey swing's rule

Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.

What you can do is to create an observer that will update your progress bar -such as
- in this instance you want to show progress of data being loaded on click of a button.
DemoHelper class implements Observable and sends updates to all observers on when certain percent of data is loaded.
Progress bar is updated via public void update(Observable o, Object arg) {

class PopulateAction implements ActionListener, Observer {

    JTable tableToRefresh;
    JProgressBar progressBar;
    JButton sourceButton;
    DemoHelper helper;
    public PopulateAction(JTable tableToRefresh, JProgressBar progressBarToUpdate) {
        this.tableToRefresh = tableToRefresh;
        this.progressBar = progressBarToUpdate;
    }

    public void actionPerformed(ActionEvent e) {
        helper = DemoHelper.getDemoHelper();
        helper.addObserver(this);
        sourceButton = ((JButton) e.getSource());
        sourceButton.setEnabled(false);
        helper.insertData();
    }

    public void update(Observable o, Object arg) {
        progressBar.setValue(helper.getPercentage());
    }
}

Shameless plug: this is from source from my demo project
Feel free to browse for more details.

一抹苦笑 2024-09-06 16:57:16

您不应该在事件调度线程之外执行任何 Swing 操作。要访问它,您需要使用运行中的代码创建一个 Runnable,然后将其传递给 SwingUtilities.invokeNow() 或 SwingUtilities.invokeLater()。问题是我们需要延迟 JProgressBar 检查以避免阻塞 Swing 线程。为此,我们需要一个计时器,它将在其自己的 Runnable 中调用 invokeNow 或稍后调用。查看 http://www.javapractices.com/topic/TopicAction。 do?Id=160 了解更多详情。

You shouldn't do any Swing stuff outside of the event dispatch thread. To access this, you need to create a Runnable with your code in run, and then pass that off to SwingUtilities.invokeNow() or SwingUtilities.invokeLater(). The problem is that we need a delay in your JProgressBar checking to avoid jamming up the Swing thread. To do this, we'll need a Timer which will call invokeNow or later in its own Runnable. Have a look at http://www.javapractices.com/topic/TopicAction.do?Id=160 for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文