当前位置: 首页 > 知识库问答 >
问题:

可观察值更改侦听器:如何访问

隆选
2023-03-14

我是JavaFX新手,已经开始转换用Swing编写的定制组件。作为最佳实践,我总是检查事件侦听器(PropertyChangeListener、MouseListener、ActionListener等)是否。)已经包含在目标对象的侦听器中,以确保同一个侦听器不会被添加两次。我试图用JavaFX做同样的事情,但是找不到任何访问侦听器列表的方法(例如,运行list.contains(listener)检查)。

我是在寻找不存在的东西吗?如果是的话,JavaFX为什么不包含这个特性(我觉得它应该包含这个特性)有什么好的理由吗?

感谢您的反馈!

共有1个答案

云承天
2023-03-14

公共API中没有机制来访问JavaFX中属性的侦听器列表。

我不确定我是否真的需要这个。您的代码控制着何时添加和删除侦听器,因此您基本上总是“知道”何时添加了侦听器。从更广泛的意义上来说,您的UI或UI组件总是某种数据形式的表示,因此侦听器是否注册只是这些数据的一个函数。

对于一个具体的例子,考虑注释中引用的用例:

public class CustomComponent extends BorderPane {

    private final Button button = new Button("Button");
    private final TextField textField = new TextField();

    private final ObjectProperty<Orientation> orientation = new SimpleObjectProperty<>();

    public ObjectProperty<Orientation> orientationProperty() {
        return orientation ;
    }

    public final Orientation getOrientation() {
        return orientationProperty().get();
    }

    public final void setOrientation(Orientation orientation) {
        orientationProperty().set(orientation);
    }

    public CustomControl(Orientation orientation) {
        setCenter(textField);

        ChangeListener<Number> widthBindingListener = (obs, oldWidth, newWidth) ->
            button.setPrefWidth(newWidth.doubleValue());

        orientationProperty().addListener((obs, oldOrientation, newOrientation) -> {
            if (newOrientation == Orientation.HORIZONTAL) {
                textField.widthProperty().removeListener(widthBindingListener);
                button.setPrefWidth(Control.USE_COMPUTED_SIZE);
                setTop(null);
                setLeft(button);
            } else {
                textField.widthProperty().addListener(widthBindingListener);
                button.setPrefWidth(textField.getWidth());
                setLeft(null);
                setTop(button);
            }
        }

        setOrientation(orientation);

    }

    public CustomControl() {
        this(Orientation.VERTICAL);
    }

    // other methods etc....
}

在本例中,您可能只使用绑定而不是侦听器:

button.prefWidthProperty().bind(Bindings
    .when(orientationProperty().isEqualTo(Orientation.HORIZONTAL))
    .then(Control.USE_COMPUTED_SIZE)
    .otherwise(textField.widthProperty()));

但这并不能证明这个概念...

请注意,就像@Clemens注释一样,您始终可以确保听众只使用习语注册一次:

textField.widthProperty().removeListener(widthBindingListener);
textField.widthProperty().addListener(widthBindingListener);

但在我看来,这似乎不是一个很好的实践:<code>RemovelListener</code>涉及遍历侦听器列表(如果尚未添加,则遍历整个侦听器列表)。此迭代是不必要的,因为信息已经在其他地方可用。

 类似资料:
  • 问题内容: 我希望消息框在用户更改文本字段中的值后立即显示。目前,我需要按Enter键才能弹出消息框。我的代码有什么问题吗? 任何帮助,将不胜感激! 问题答案: 将侦听器添加到为您自动创建的基础文档中。

  • 问题内容: 我希望在用户更改文本字段中的值后立即显示消息框。目前,我需要按Enter键才能弹出消息框。我的代码有什么问题吗? 任何帮助,将不胜感激! 问题答案: 将侦听器添加到为你自动创建的基础文档中。

  • 在我的代码中,如果用户在ComboBox 2中输入值,它将反映在TextField中,但是如果用户从ComboBox 1的下拉列表中选择,而不更改ComboBox 2中的值,那么TextField中的值将保持不变,它不会更改。我做错了吗? 测试2。txt:1任何帮助都将不胜感激!

  • 也许我错过了什么。我找不到Observable及其语法的简单教程。我在使用Angular,我需要从服务调用一个函数(在组件中定义)。我读了这个解决方案。但是我不知道如何更改在服务中创建的Observable中的值(也许创建不是最好的方法)。 我在解决方案中有一个组件: } 这是我的服务:

  • 问题内容: 我想一种添加到我当过用户更改的,它的值,应用程序在控制台上打印的东西。 我进行了搜索,发现以下非常相似的问题:JTextField的值更改侦听器 提到的问题的答案非常清楚和有效,但是不幸的是,它仅对(Not )有用,因为它说您应该像这样使用DocumentListener: 但是在JavaFX的TextField中,您无法执行此操作。所以?解决办法是什么? (使用代码进行描述可能会很好

  • 问题内容: 我一直在类设计方面遇到问题,直到我发现了可观察的(使用观察者设计模式),因此使用它创建了一个小型应用程序,从而解决了我的问题。我为使用一个好的原则解决问题感到高​​兴和自豪。 为什么建议张贴者不要使用可观察的,而要告诉他们使用propertychangelistenr?使用observable是否有任何问题? 问候 问题答案: 观察者和侦听器模式非常相似。但是观察者有一个弱点:所有可观