Multithreading – JavaFX task Updatevalue triggers only the first change event

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
分享
二维码
< <上一篇
下一篇>>