即使 oldVaule 和 newValue 相同,如何使 JavaFX 属性侦听器触发事件​​?

not*_*lty 4 java javafx

让我们考虑一个示例代码:

SimpleIntegerProperty simpleIntegerProperty = new SimpleIntegerProperty(0);
simpleIntegerProperty.addListener((observable, oldValue, newValue) -> {
  // execution code when the event is fired.
});
Run Code Online (Sandbox Code Playgroud)

当我使用方法设置新值时setValue(),如果 oldValue 和 newValue 相同,则不会触发该事件。仅当它们不同时。

一个例子:

  • 我有一个包含一些“元素”ListView<Element>的绑定ObservableList<Element>
  • 我可以在应用程序的不同位置添加更多元素。
  • 有一个“开始”按钮可以启动一个过程 - 它遍历列表并对每个元素执行一些操作。
  • AProcedure是一个不同的班级。它对元素做了一些事情,并且还包含SimpleIntegerPorperty-currentlyChosenElementIndex来指示当前所选元素的索引。

当当前元素正在进行时,我希望ListView显示这一点。现在,在该过程中,GUI 被阻止,并且ListView在继续进行时在 上选择当前元素。程序结束后,应用程序重置currentlyChosenElementIndex为零,这是我遇到问题的索引。当该过程启动时,不会选择第一个元素,因为该应用程序setValue()与先前的元素相同。

有什么办法可以改变这种情况吗?

Flo*_*d2d 5

你不能通过简单地使用SimpleIntegerProperty类来做到这一点。但您可以扩展类并添加所需的功能。创建一个这样的类

public class NotifySetIntegerProperty extends SimpleIntegerProperty {
    private OnSetValueListener valueListener;

    public NotifySetIntegerProperty(int initialValue) {
        super(initialValue);
    }

    @Override
    public void set(int newValue) {
        super.set(newValue);
        if(valueListener!= null) {
            valueListener.onValueSet(newValue);
        }
    }

    public void setValueListener(OnSetValueListener valueListener) {
        this.valueListener = valueListener;
    }

    public interface OnSetValueListener {
        void onValueSet(int value);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用它并在调用setValueset方法时收到通知

NotifySetIntegerProperty property = new NotifySetIntegerProperty(0);
property.setValueListener(new NotifySetIntegerProperty.OnSetValueListener() {
    @Override
    public void onValueSet(int value) {
        System.out.println(value);
    }
});
property.setValue(1);
property.setValue(0);
Run Code Online (Sandbox Code Playgroud)

会输出

1
0
Run Code Online (Sandbox Code Playgroud)