在for循环中更新ProgressBar值 [英] Updating ProgressBar value within a for loop

查看:149
本文介绍了在for循环中更新ProgressBar值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在for循环中更新ProgressBar值.它的进度应该每100毫秒更新一次,但不幸的是它没有用!这是代码:

I attempted to update a ProgressBar value within a for loop. Its progress should update every 100 miliseconds but unfortunately it didn't work! Here's the code:

pb = new ProgressBar(0);
Button btn = new Button("Start!");
btn.setOnAction(new EventHandler<ActionEvent>(){
    @Override
    public void handle(ActionEvent event) {
        for(int i = 0; i <=100; i++){
            position = i;
            Platform.runLater(new Runnable(){
                @Override
                public void run() {
                    pb.setProgress(position);
                    System.out.println("Index: "+position);
                }
            });
            try{
                Thread.sleep(100);
            }catch(Exception e){ System.err.println(e); }
        }
    }
});

问题1:我期望上面的代码每100毫秒更新一次进度条,但是它没有用.为什么?

Question 1: I was expecting the above code to update the progressbar every 100 miliseconds but it didn't work. Why?

问题2:我在循环中调用了System.out.println("Index: "+position);.我以为输出应该是1..2..3..4...,但是我错了.输出是这样的:

Question 2: I called System.out.println("Index: "+position); within the loop. I assumed that the output should be 1..2..3..4... but I was wrong. The output is something like this:

Index: 100
Index: 100
Index: 100
Index: 100
Index: 100
Index: 100
Index: 100

推荐答案

背景

    当您在其他线程上时,调用
  1. Platform.runLater()JavaFX Application thread上执行某些操作.当您已经在JavaFX应用程序线程上并在队列中添加所有这些项目时,便每100毫秒运行一次它,因为该线程已经在忙于运行循环并正在休眠:)

  1. Platform.runLater() is called to execute something on the JavaFX Application thread when you are on some other thread. You are running it every 100ms when you are already on the JavaFX application thread adding all these items in queue, because the thread is already busy running the loop and sleeping :)

因此,在线程可以自由执行它们之后(即在完成循环之后),它将在队列中运行所有内容.

So it runs everything in queue after the thread is free to execute them i.e. after finishing the loop.

还有另一个问题, ProgressBar 具有 progressproperty ,其值可以在0到1之间,其中0表示0%,1表示100%.如果要更新进度条,则需要将进度设置为0.1到1.0之间的值.

There is another problem, ProgressBar has a progressproperty whose value can be between 0 and 1, where 0 represents 0% and 1 represents 100%. If you want to update the progress bar, you would want to set the progress with values between 0.1 to 1.0.

如何修复

您应该在按钮的动作上启动一个新的线程,并让其处理循环.您可以在此线程内使用Platform.runLater,而不会阻塞JavaFX应用程序线程.

You should start a new Thread on the button's action and let it handle the loop. You can use Platform.runLater inside this thread, without choking the JavaFX application thread.

我将运行以下内容:

btn.setOnAction(event -> {
    new Thread(() -> {
         for(int i = 0; i <=100; i++){
            final int position = i;
            Platform.runLater(() -> {
                pb.setProgress(position/100.0);
                System.out.println("Index: " + position);
            });
            try{
                Thread.sleep(100);
            }catch(Exception e){ System.err.println(e); }
         }
    }).start();
});

注意: 此答案更多地强调了OP出了错的地方以及他如何纠正它.如果您使用JavaFX,则可能希望使用更好的方法,即使用 updateProgress() 来更新ProgressBar的进度,如@kleopatra在其解决方案中所述.

这篇关于在for循环中更新ProgressBar值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆