1

我对 javafx 有一点问题。我添加了一个这样的更改监听器:

private final ChangeListener<String> pageItemSelected = new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue){
    pageGotSelected(newValue);
}
};

现在问题来了:如果我更改这样的页面项目:

 guiPageList.setValue(model.getCurrentTargetPage());

该事件也被触发(因为它通过用鼠标或键选择某些东西)被触发。有没有办法禁用事件触发或其他方式?我只需要事件,如果用户选择了元素,而不是如果我使用 setValue() 函数更改它......也许会消耗事件,但我不知道这会是什么类型的事件。

提前致谢!!!

4

3 回答 3

8

您可以暂时删除侦听器并再次添加它:

guiPageList.getSelectionModel().selectedItemProperty().removeListener(pageItemSelected);
guiPageList.setValue(model.getCurrentTargetPage());
guiPageList.getSelectionModel().selectedItemProperty().addListener(pageItemSelected);
于 2012-09-25T10:24:50.423 回答
7

或者,您可以使用另一个侦听器实现来装饰侦听器,代码将类似于:

class InvalidationListenerEventBlocker implements InvalidationListener {
    InvalidationListener decoratedListener;
    boolean block;
    public void invalidated(Observable observable) {
        if(!block) {
            decoratedListener.invalidated(observable);
        }
    }
}

为块布尔值添加一个设置器,并通过构造函数发送侦听器。将 block 设置为 true 以停止事件。

于 2012-09-25T12:38:44.903 回答
0

这是一个非常老的问题,但我找到了一些我个人使用的解决方案,它是可重用的,不需要存储对侦听器的引用(但它需要对暴露/消音属性的引用)。

所以首先是概念:我们将创建 lambda ( InvalidationListener),仅当上述暴露/消音属性设置为 true/false 时才会调用它。为此,我们将定义另一个提供描述行为的功能接口:

@FunctionalInterface
private interface ManageableInvalidationListener
extends InvalidationListener {

    public static InvalidationListener exposing(
            BooleanProperty expose,
            ManageableInvalidationListener listener) {
        return ob -> {
            if (expose.get()) {
                listener.invalidate(ob);
            }
        };
    }

    public static InvalidationListener muffling(
            BooleanProperty muffle,
            ManageableInvalidationListener listener) {
        return ob -> {
            if (!muffle.get()) {
                listener.invalidated(ob);
            }
        }
    }

    public abstract void invalidated(Observable ob);
}

这个接口定义了我们将在代码中使用的两个静态方法。我们传递一个转向属性作为第一个参数(它将告诉是否应该调用侦听器)和要执行的实际实现,何时调用它。请注意,无需扩展InvalidationListener,但我想ManageableInvalidationListenerInvalidationListener.

因此,exposing如果我们需要创建一个(manageabale)侦听器,如果expose属性的值为true. 在其他情况下,我们将使用 来创建侦听器muffling,如果true转向属性意味着,嗯,消音通知。

如何使用它?

    //- Let's make life easier and import expose method statically
    import static ManageableInvalidationListener.exposing;

// ...

    //- This is the steering property.
    BooleanProperty notify = new SimpleBooleanProperty(true);

    //- This is our main property with the listener.
    ObjectProperty<Foobar> foobar = new SimpleObjectProperty<>();

    //- Let's say we are going to notify the listener, if the
    //  notify property is set to true.
    foobar.addListener(exposing(notify, ob -> {
        //- Here comes the InvalidListener code.
    }));

然后在代码中的某处:

    //- Listener will be notified as usual.
    foobar.set(new Foobar());

    //- Now temporarily disable notifications.
    notify.set(false);
    //- The listener will not get the notification this time.
    foobar.set(new Foobar());
    //- Re-enable notifications.
    notify.set(true);

希望这会有所帮助。您可以随意使用本文中的代码。

于 2020-01-15T15:41:29.897 回答