imagen controles componentes color boton javafx-2

javafx-2 - controles - set label color javafx



Tarea de fondo periĆ³dica de JavaFX (3)

Intento ejecutar el hilo de fondo de la aplicación JavaFX periódicamente, lo que modifica algunas propiedades de la GUI.

Creo que sé cómo usar las clases de Task y Service de javafx.concurrent y no puedo entender cómo ejecutar dicha tarea periódica sin utilizar el método Thread#sleep() . Sería bueno si pudiera usar algún Executor de los Executors fabricar métodos ( Executors.newSingleThreadScheduledExecutor() )

Intenté ejecutar Runnable cada 5 segundos, lo que reinicia javafx.concurrent.Service pero se cuelga inmediatamente cuando se llama a service.restart o incluso service.getState() .

Así que finalmente uso Executors.newSingleThreadScheduledExecutor() , que dispara mi Runnable cada 5 segundos y Runnable ejecuta otro Runnable usando:

Platform.runLater(new Runnable() { //here i can modify GUI properties }

Se ve muy desagradable :( ¿Hay una mejor manera de hacerlo con clases de Task o Service ?


Aquí hay una solución que usa Java 8 y ReactFX . Supongamos que desea volver a calcular periódicamente el valor de Label.textProperty() .

Label label = ...; EventStreams.ticks(Duration.ofSeconds(5)) // emits periodic ticks .supplyCompletionStage(() -> getStatusAsync()) // starts a background task on each tick .await() // emits task results, when ready .subscribe(label::setText); // performs label.setText() for each result CompletionStage<String> getStatusAsync() { return CompletableFuture.supplyAsync(() -> getStatusFromNetwork()); } String getStatusFromNetwork() { // ... }

En comparación con la solución de Sergey, no dedicas todo el hilo para obtener el estado de la red, sino que utilizas el grupo de hilos compartidos para eso.


Preferiría la PauseTransition:

PauseTransition wait = new PauseTransition(Duration.seconds(5)); wait.setOnFinished((e) -> { /*YOUR METHOD*/ wait.playFromStart(); }); wait.play();


Puede usar Timeline para qué importa:

Timeline fiveSecondsWonder = new Timeline(new KeyFrame(Duration.seconds(5), new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("this is called every 5 seconds on UI thread"); } })); fiveSecondsWonder.setCycleCount(Timeline.INDEFINITE); fiveSecondsWonder.play();

para los procesos en segundo plano (que no le hacen nada a la IU) puedes usar el antiguo buen java.util.Timer :

new Timer().schedule( new TimerTask() { @Override public void run() { System.out.println("ping"); } }, 0, 5000);