ChangeListener作为私有类

时间:2016-06-29 18:17:45

标签: java generics javafx observable changelistener

我正在开发一款游戏,我正在尝试为角色的健康实施ChangeListener。 我为healthProperty定义了一个getter,它实际上是SimpleIntegerProperty的一个实例

我已经将它作为lambda表达式工作了:

character1.healthProperty().addListener( ((observable, oldValue, newValue) -> {
        System.out.println(observable);
        System.out.println(oldValue);
        System.out.println(newValue);
    }) );

当角色受到伤害时,会打印出来:

IntegerProperty [value:333]

350

333

问题是我希望能够为游戏中的每个角色重用这个侦听器,所以我希望它成为一个内部类,但我不能正确地获得类型,到目前为止我已经得到了这个:

private class HealthPropertyListener implements ChangeListener<IntegerProperty> {

    @Override
    public void changed(ObservableValue<IntegerProperty> observable, Integer oldValue, Integer newValue) {
        // Do something
    }

它没有编译,因为它告诉我,我没有正确地覆盖该方法。

如果我这样做,它可以工作,但我必须将Object转换为Integer才能使用它们。有没有办法逃脱这个丑陋的演员?

private class HealthPropertyListener implements ChangeListener {

    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        //Do something
    }

3 个答案:

答案 0 :(得分:2)

SimpleIntegerProperty实现ObservableValue<Number>,因此正确的签名应为:

public void changed (ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue)

顺便说一下,使用Java 8,你真的不必为此创建一个类 - 你可以使用一种方法:

private void healthChanged (ObservableValue<? extends Number> obs, Number oldValue, Number newValue) {
    ...
}

...
// inside a method in the same class
character1.healthProperty().addListener(this::healthChanged);

另请参阅:Why does LongProperty implement Property but not Property?

答案 1 :(得分:2)

请注意SimpleIntegerProperty实施ObservableValue<Number>。因此,您需要ChangeListener<Number>。此类型参数的changed方法的正确签名为

public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue)

请参阅javadoc for ChangeListenerjavadoc for SimpleIntegerProperty

答案 2 :(得分:1)

查看public interface ChangeListener<T>的{​​{3}}方法:

void changed(ObservableValue<? extends T> observable, T oldValue, T newValue)

基于此,正确的形式是:

private class HealthPropertyListener implements ChangeListener<IntegerProperty> {

    @Override
    public void changed(ObservableValue<? extends IntegerProperty> observable, IntegerProperty oldValue,
            IntegerProperty newValue) {
    }
}

这个问题的答案可能有所帮助:

changed