Search code examples
javagenericsjavafxobservablechangelistener

ChangeListener as a private class


I'm developing a game and I'm currently trying to implement a ChangeListener for the character's Health. I've defined a getter for the healthProperty which is actually an instance of SimpleIntegerProperty

I've already got it working as a lambda expression:

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

When the character takes damage it prints out:

IntegerProperty [value: 333]

350

333

The thing is that I want to be able to reuse this listener for every character in-game, so I'd like it to be an inner class, but I can't get the types right, so far i've got this:

private class HealthPropertyListener implements ChangeListener<IntegerProperty> {

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

It doesn't compile cause it tells me that i'm not overriding the method correctly.

If I do it this other way, it works, but I'll have to cast the Object to Integer in order to use them. Is there a way to escape that ugly cast?

private class HealthPropertyListener implements ChangeListener {

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

Solution

  • Note that SimpleIntegerProperty implements ObservableValue<Number>. Therefore you need a ChangeListener<Number>. The correct signature for the changed method in for this type parameter would be

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

    See javadoc for ChangeListener and javadoc for SimpleIntegerProperty