javafx - 如何禁用不是从用户触发的事件

时间:2012-09-25 08:26:33

标签: events javafx

我对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()函数更改它... 也许正在消耗这个事件,但我不知道会是什么样的事件。

提前致谢!!!

3 个答案:

答案 0 :(得分:8)

您可以暂时删除侦听器并重新添加:

guiPageList.getSelectionModel().selectedItemProperty().removeListener(pageItemSelected);
guiPageList.setValue(model.getCurrentTargetPage());
guiPageList.getSelectionModel().selectedItemProperty().addListener(pageItemSelected);

答案 1 :(得分:6)

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

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

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

答案 2 :(得分:0)

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

所以首先有了概念:我们将创建lambda(InvalidationListener),只有在上述的expose / muffling属性设置为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保持同步。

因此,如果我们需要创建一个{manageabale}侦听器,如果exposing属性的值为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);

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