是否错误地声明了JavaFX SimpleDoubleProperty.addListener方法?

时间:2014-03-21 05:09:10

标签: java javafx

在我的代码中,我对收听SimpleDoubleProperty的更改感兴趣。

以下是addListener方法的签名:

public void addListener(ChangeListener<? super Number> listener)

触发Double值更改的属性如何要求它的侦听器侦听Number或其中一个超类型?不应该这样定义:

 public void addListener(ChangeListener<? extends Double> listener)

具有属性的示例类:

HasObservableProperty.java

public class HasObservableProperty {
     private final SimpleDoubleProperty progress = new SimpleDoubleProperty();
     ...
     public void addProgressChangeListener(ChangeListener<? super Number> listener) {
         progress.addListener(listener);
     }
}

就这样,我有一个听众定义为:

class ProgressBarNotifier implements ChangeListener<Number> {
    private final ProgressBar progress_bar;

    public ProgressBarNotifier(ProgressBar bar) {
        progress_bar = bar;
   }
   @Override
   public void changed(ObservableValue<? extends Number> progress, Number oldValue,
                        Number newValue) {
        progress_bar.setProgress((Double)newValue);
   }
}

了解我是如何被迫将更改后的值转换为Double

progress_bar.setProgress((Double)newValue);

如果addListener方法具有建议的签名,则情况不应该如此。

所以,问题是,SimpleDoubleProperty.addListener方法是否被错误地声明了?

PS:适用于SimpleDoubleProperty的内容似乎适用于其他可观察对象,例如SimpleStringProperty

1 个答案:

答案 0 :(得分:2)

简单的答案是&#34;因为它是如何完成的&#34;。请注意,正如Uluk在评论中指出的那样,您不会被强制转换:您可以在侦听器方法中收到的doubleValue()引用上调用Number

DoubleProperty背后有一个非常复杂的层次结构。相关部分是DoubleProperty implements ObservableDoubleValue extends ObservableNumberValue extends ObservableValue<Number>ObservableValue<T>定义了addListener(ChangeListener<? super T>)方法,因此DoubleProperty必须定义addListener(ChangeListener<? super Number>)

这是最好的方法吗?我实际上并不这么认为:我认为可以使ObservableNumberValue通用:ObservableNumberValue<T extends Number> extends ObservableValue<T>然后ObservableDoubleValue extends ObservableNumberValue<Double>,此时addListener(...)方法将放宽到addListener(ChangeListener<? super Double>),这正是您正在寻找的。

层次结构的其他部分:PropertyWritableDoubleValueWritableNumberValueWritableValue等可能会阻止此结构;但无论如何这种变化现在都是不可能的,所以我们不知道我们所拥有的是否是一个错误,或者是否有一些复杂的原因它必须是这样我不是意识到。它偶尔会很烦人,但正如所指出的那样,你总是可以使用doubleValue()

在许多情况下,例如您展示的那种情况,您也可以使用绑定,例如progressBar.progressProperty().bind(progress);