首页 > 解决方案 > 绑定属性的更改侦听器仅接收到 Task 中 messageProperty 的最后一次更新

问题描述

在我的 JavaFX-11 fxml 应用程序中,我有一个简单的测试任务:

public class TestTask extends Task<Void> {
    @Override
    protected Void call() throws Exception {
         updateMessage("TestTask message before sleep 1");
        Thread.sleep(1000);
         updateMessage("TestTask message after  sleep 1");
        Thread.sleep(1000);
         updateMessage("TestTask message after sleep 2");
        Thread.sleep(1000);
         updateMessage("TestTask message after sleep 3");
        return null;
    }
}

在 fxml 控制器类中,我将一个属性绑定到 Task 消息属性,以及一个我想用来在日志窗口中写入消息的更改侦听器:

TestTask testTask = new TestTask();
SimpleStringProperty taskMessage = new SimpleStringProperty();
taskMessage.bind(testTask.messageProperty());
taskMessage.addListener(cl -> {
   System.out.println("taskMessage change listener invoked, new value = " + taskMessage.getValue());
   msgList.add(taskMessage.getValue());
});

我这样开始线程:

Thread computationThread = new Thread(testTask);
computationThread.setDaemon(true);
computationThread.start();

控制台显示以下消息:

taskMessage change listener invoked, new value = 
taskMessage change listener invoked, new value = TestTask message after sleep 3

我知道“可以合并中间消息值以保存事件通知”,但这里我们只讨论 4 条消息,间隔 1 秒。他们几乎无法淹没事件队列,所以我不明白为什么绑定属性只更新两次:一次是空消息,第二次是最后一条消息。

标签: javafx

解决方案


使用 aChangeListener是正确的做法。当我开始编写 lambda 表达式时,IDE 建议了一个适用的侦听器列表,而我不小心接受了InvalidationListener.


推荐阅读