JavaFX 中的 registerChangeListener 方法有什么作用?

What does the registerChangeListener method do in JavaFX?

我最近开始使用 JavaFX。我在我的项目中将 JDK 从 8 更改为 11 并且有一个 class 使用此方法:

public class LabeledColorPickerSkin extends ColorPickerSkin {
    public LabeledColorPickerSkin(final LabeledColorPicker colorPicker) {
        super(colorPicker);
        registerChangeListener(colorPicker.valueProperty(), "VALUE");
        text.setText(colorPicker.text);
        updateColor();
     }
}

这里用到:

import javafx.scene.control.ColorPicker;
import javafx.scene.control.Skin;

public class LabeledColorPicker extends ColorPicker {
    public LabeledColorPicker()
    {
        super();
        getStyleClass().addAll("labeled-color-picker",
                "text-visible");
    }
    /** {@inheritDoc} */
    @Override protected Skin<?> createDefaultSkin() {
        return new LabeledColorPickerSkin(this);
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    String text;
}

在版本 8 中,方法如下所示:

protected final void registerChangeListener(ObservableValue<?> property, String reference) {
    if (changeListenerHandler == null) {
        changeListenerHandler = new MultiplePropertyChangeListenerHandler(p -> {
            handleControlPropertyChanged(p);
            return null;
        });
    }
    changeListenerHandler.registerChangeListener(property, reference);
}

现在看起来像这样:

protected final void registerChangeListener(ObservableValue<?> property, Consumer<ObservableValue<?>> consumer) {
    if (lambdaChangeListenerHandler == null) {
        lambdaChangeListenerHandler = new LambdaMultiplePropertyChangeListenerHandler();
    }
    lambdaChangeListenerHandler.registerChangeListener(property, consumer);
}

我不明白此方法的作用以及如何为 JavaFX 11 重写此代码。

此方法用于注册控件属性的侦听器。它确保只有一个侦听器用于此目的,此外还确保使用 WeakChangeListener 允许皮肤被垃圾收集(如果您更换它)。

在 JavaFX 8 中,包含 class SkinBase(以及像 ColorPickerSkin 这样的子class)是内部 API 的一部分并使用String 会收到属性更改通知(哎呀)。当 属性 被改变时,handleControlPropertyChanged 方法被调用接收,字符串作为第二个参数传递给 registerChangeListener 方法作为参数。

以下代码来自 ColorPickerSkin 的源代码,但您正在使用的代码应该包含类似的内容:

@Override protected void handleControlPropertyChanged(String p) {
    super.handleControlPropertyChanged(p);

    if ("SHOWING".equals(p)) {
        ...
    } else if ("VALUE".equals(p)) {
        /* Some logic for updating the GUI */
    }
}

要为新的 (JavaFX 9+) API 重写代码,您需要移动执行的逻辑,如果 "VALUE" 作为参数传递给此方法的方法 Consumer<ObservableValue<?>>:

public LabeledColorPickerSkin(final LabeledColorPicker colorPicker) {
    super(colorPicker);
    registerChangeListener(colorPicker.valueProperty(), observable -> {
        /* Some logic for updating the GUI */
    });
    text.setText(colorPicker.text);
    updateColor();
}