Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

user interface - ProgressBar in Javafx does not update in onAction block

I'd like to have a progress bar that updates inside an onAction block. For some reason in the following code, the progress bar doesn't update until it exits the onAction block. I get no progress for nine seconds and then 90%. The System.out prints just fine.

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();
    }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Long form of tomsomtom's precise answer:

If you use the JavaFX Thread to do this kind of long term work, you stop the UI from updating etc. So you have to run your worker in a sparate thread. If you run in a separate Thread, all GUI operatione like progress.setProgress() have to be passed back to the JavaFX Thread using runLater() as JavaFX is not multithreaded.

Try this in your 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();
        }

    } );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...