加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – Javafx Task.updateValue仅触发第一个更改事件

发布时间:2020-12-15 04:30:44 所属栏目:Java 来源:网络整理
导读:我想观察一个任务的valueProperty,并在updateValue()改变时采取行动.改变事件似乎只是在第一次更新时被触发了. Oracle’s getValue document有一个部分暗示重复调用UpdateValue以返回部分结果是犹太的.也许我不理解“更新合并”的含义. 最低范例 import java
我想观察一个任务的valueProperty,并在updateValue()改变时采取行动.改变事件似乎只是在第一次更新时被触发了.

Oracle’s getValue document有一个部分暗示重复调用UpdateValue以返回部分结果是犹太的.也许我不理解“更新合并”的含义.

最低范例

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

解决方法

任务的值只更改一次.最初它是null.在第一次迭代时,它会更改,因此值== list,并且在每次后续迭代中,value == list(即没有进一步的更改).

你可能想:

>通过调用Platform.runLater(() – > list.add(addMe))更新FX应用程序线程上的列表;>安排观察列表本身,而不是任务的value属性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读