Multithreading – JavaFX task Updatevalue triggers only the first change event
•
Java
I want to observe the valueproperty of a task and take action when updatevalue () changes The change event seems to be triggered only on the first update
Oracle's getValue document has a section that implies that it is necessary to call updatevalue repeatedly to return some results Maybe I don't understand the meaning of "update and merge"
Minimum example
import javafx.application.Application; import javafx.application.Platform; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.scene.Scene; import javafx.scene.control.ListView; import javafx.stage.Stage; public class Main extends Application { MyTask task = new MyTask(); ListView<String> listView = new ListView<>(); @Override public void start(Stage primaryStage) throws Exception { primaryStage.setScene(new Scene(listView)); primaryStage.show(); Thread taskThread = new Thread(task); taskThread.start(); task.valueproperty().addListener( (ob,old,nw) -> listView.getItems().addAll(nw) ); // Only fires once. //task.lastString.addListener( iv -> listView.getItems().addAll(task.lastString.getValue()) ); // Fires every add } public static void main(String[] args) { launch(args); } } class MyTask extends Task<ObservableList<String>> { ObservableList<String> list = FXCollections.observableArrayList(); public ReadOnlyObjectWrapper<String> lastString = new ReadOnlyObjectWrapper<>(new String()); Integer maxWork = 4; @Override protected ObservableList<String> call() throws Exception { for( Integer stringNo=0; stringNo<maxWork; stringNo++) { Thread.sleep(500); String addMe = new String("Thread string " + stringNo); list.add(addMe); updateProgress(stringNo,maxWork); updateValue(list); // Only fires one change event Platform.runLater( () -> { lastString.setValue(addMe); // Works as expected. } ); } return list; } }
Solution
The value of the task is changed only once Initially it was null At the first iteration, it changes, so the value = = list, and at each subsequent iteration, value = = list (i.e. no further changes)
You may want to:
>By calling platform runLater(() – > list. Add (addme)) updates the list on the FX application thread; > Schedule the watch list itself, not the value attribute of the task
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码