Implementing an ObservableValue
Asked Answered
S

2

9

I have this object:

public class Oggetto{
    private int value;
    private boolean valid;

    public Oggetto(int value, boolean valid) {
        this.value = value;
        this.valid = valid;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public boolean isValid() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }    
}

and I would like implement an Observable object that fires events when something inside changes Here the observable object:

public class OggettoOsservabile implements ObservableValue<Oggetto>{

    private Oggetto value;

    OggettoOsservabile(int i, boolean b) {
        this.value=new Oggetto(i, b);
    }
    @Override
    public void addListener(ChangeListener<? super Oggetto> listener) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override
    public void removeListener(ChangeListener<? super Oggetto> listener) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override
    public Oggetto getValue() {
        return value;
    }
    @Override
    public void addListener(InvalidationListener listener) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override
    public void removeListener(InvalidationListener listener) {
        throw new UnsupportedOperationException("Not supported yet."); 
    }  
}

i dont know how to proceed in order to detect a change in the class "Oggetto" and send a notification to the registeres listener.

OggettoOsservabile oggetto = new OggettoOsservabile(1, false);              
oggetto.addListener(new ChangeListener<Oggetto>() {
     public void changed(ObservableValue<? extends Oggetto> observable, Oggetto oldValue, Oggetto newValue) {
           System.out.println("changed " + oldValue + "->" + newValue);   
     }
});
Shantelleshantha answered 11/10, 2014 at 10:41 Comment(0)
G
6

Implement your Oggetto class using standard JavaFX Properties:

import javafx.beans.property.BooleanProperty ;
import javafx.beans.property.IntegerProperty ;
import javafx.beans.property.SimpleBooleanProperty ;
import javafx.beans.property.SimpleIntegerProperty ;

public class Oggetto {

    private final IntegerProperty value = new SimpleIntegerProperty() ;

    public final IntegerProperty valueProperty() {
        return value ;
    }

    public final int getValue() {
        return value.get();
    }

    public final void setValue(int value) {
        this.value.set(value);
    }

    private final BooleanProperty valid = new SimpleBooleanProperty();

    public final BooleanProperty validProperty() {
        return valid ;
    }

    public final boolean isValid() {
        return valid.get();
    }

    public final void setValid(boolean valid) {
        this.valid.set(valid);
    }

    public Oggetto(int value, boolean valid) {
        setValue(value);
        setValid(valid);
    }
}

This may be all you need, as you can just observe the individual properties. But if you want a class that notifies invalidation listeners if either property changes, you can extend ObjectBinding:

import javafx.beans.binding.ObjectBinding ;

public class OggettoObservable extends ObjectBinding {

    private final Oggetto value ;

    public OggettoObservable(int value, boolean valid) {
        this.value = new Oggetto(value, valid);
        bind(this.value.valueProperty(), this.value.validProperty());
    }

    @Override
    public Oggetto computeValue() {
        return value ;
    }
}
Gybe answered 11/10, 2014 at 15:3 Comment(3)
Thanks! Your implementation make sense, BTW I cannot understand when shoud I implements Observable and ObservableValue.Shantelleshantha
The API is a bit too fine-grained for my liking. But Observable is just something that notifies listeners when it is invalid. ObservableValue additionally wraps a value (it has a getValue() method and can notify ChangeListeners when the value actually changes.Gybe
When I do this I get a warning that ObjectBinding should have a type parameter. So should it be extends ObjectBinding<Oggetto>?Berube
R
-2
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

    public class VerySimply implements ObservableValue<Integer> {
    private int newValue;
    public ChangeListener<Integer> listener = new ChangeListener<Integer>() {
        @Override
        public void changed(ObservableValue<? extends Integer> observable, Integer oldValue, Integer newValue) {
            System.out.println(" :) "+ newValue.intValue());
        }
    };

    @Override
    public void addListener(ChangeListener<? super Integer> listener) {

    }

    @Override
    public void removeListener(ChangeListener<? super Integer> listener) {

    }

    @Override
    public Integer getValue() {
        return newValue;
    }

    @Override
    public void addListener(InvalidationListener listener) {

    }

    @Override
    public void removeListener(InvalidationListener listener) {

    }

    public void setNewValue(int newValue) {
        int oldValue = this.newValue;
        this.newValue = newValue;
        listener.changed(this,oldValue,this.newValue);

    }
}
Result answered 23/7, 2019 at 19:48 Comment(2)
and in the class with the main method :VerySimply x = new VerySimply(); x.addListener(x.listener); x.setNewValue(10000);Result
plain wrong, that's not a valid implementation of ObservableValue: it is violating its notification contract (which is the whole essence of having an observable).Franckot

© 2022 - 2024 — McMap. All rights reserved.