user-interface javafx progress

user interface - ProgressBar en Javafx no se actualiza en el bloque onAction



user-interface (2)

Está bloqueando el hilo del evento javafx, necesita hacer el trabajo en otro hilo y sincronizar solo la llamada setProgress con Platform.runLater

Me gustaría tener una barra de progreso que se actualice dentro de un bloque onAction . Por alguna razón en el siguiente código, la barra de progreso no se actualiza hasta que sale del bloque onAction . No obtengo progreso durante nueve segundos y luego 90%. El System.out imprime muy bien.

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


Forma larga de la respuesta precisa de tomsomtom:

Si utiliza JavaFX Thread para hacer este tipo de trabajo a largo plazo, detiene la actualización de la interfaz de usuario, etc. Por lo tanto, debe ejecutar su trabajador en un hilo disperso. Si se ejecuta en un subproceso independiente, todas las operaciones de la GUI, como progress.setProgress (), deben devolverse al subproceso JavaFX mediante runLater (), ya que JavaFX no es multiproceso.

Prueba esto en tu acción:

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