【问题标题】:ProgressBar in Javafx does not update in onAction blockJavafx 中的 ProgressBar 不会在 onAction 块中更新
【发布时间】:2015-01-21 07:33:00
【问题描述】:

我想要一个在onAction 块内更新的进度条。出于某种原因,在以下代码中,进度条在退出 onAction 块之前不会更新。我在 9 秒内没有任何进展,然后是 90%。 System.out 打印得很好。

package net.snortum.play;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class ProgressBarTester extends Application {

    public static void main( String[] args ) {
        launch( ProgressBarTester.class, args );
    }

    @Override
    public void start( final Stage stage ) throws Exception {
        final GridPane grid = new GridPane();
        grid.setAlignment( Pos.CENTER );
        grid.setHgap( 10 );
        grid.setVgap( 10 );
        grid.setPadding( new Insets( 25, 25, 25, 25 ) );

        final Text title = new Text( "Test Progress Bar" );
        int col = 0, row = 0, colSpan = 2, rowSpan = 1;
        grid.add( title, col, row, colSpan, rowSpan );

        col = 0; 
        row++;
        grid.add( new Label( "Progress:" ), col, row );
        col = 1; 
        final ProgressBar progress = new ProgressBar( 0.0 );
        grid.add( progress, col, row );

        final HBox hbox = new HBox();
        hbox.setAlignment( Pos.BASELINE_RIGHT );
        final Button submit = new Button( "Go" );
        hbox.getChildren().add( submit );
        col = 1; 
        row++;
        grid.add( hbox, col, row );

        submit.setOnAction( new EventHandler<ActionEvent>() {

            @Override
            public void handle( ActionEvent event ) {
                double size = 10.0;
                for (double i = 0.0; i < size; i++){
                    progress.setProgress( i / size );
                    System.out.printf("Complete: %02.2f%n", i * 10);

                    try {
                        Thread.sleep(1000); 
                    } catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                    }
                }
            }

        } );

        final Scene scene = new Scene( grid );
        stage.setScene( scene );
        stage.setTitle( "Test Progress Bar" );
        stage.show();
    }

}

【问题讨论】:

    标签: user-interface javafx progress


    【解决方案1】:

    tomsomtom 的精确答案的长形式:

    如果你使用 JavaFX 线程来做这种长期工作,你会阻止 UI 更新等。所以你必须在一个单独的线程中运行你的工作线程。如果您在单独的线程中运行,所有 GUI 操作(如 progress.setProgress())都必须使用 runLater() 传递回 JavaFX 线程,因为 JavaFX 不是多线程的。

    在你的 Action 中试试这个:

        submit.setOnAction( new EventHandler<ActionEvent>() {
            @Override
            public void handle( ActionEvent event ) {
                double size = 10.0;
                new Thread(){
                    public void run() {
                        for (double i = 0.0; i < size; i++){
                            final double step = i;
                            Platform.runLater(() -> progress.setProgress( step / size ));
                            System.out.printf("Complete: %02.2f%n", i * 10);
    
                            try {
                                Thread.sleep(1000); 
                            } catch(InterruptedException ex) {
                                Thread.currentThread().interrupt();
                            }
                        }
                    }
                }.start();
            }
    
        } );
    

    【讨论】:

      【解决方案2】:

      您正在阻塞 javafx 事件线程,您需要在另一个线程中完成工作并仅将 setProgress 调用与 Platform.runLater 同步回

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-17
        • 2013-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多