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
二维码
