Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use WeakChangeListener with JavaFx?

I wrote my TableCell implementation based on TableCell. I'm using ChangeListener, but it is not garbage collected. How to use WeakChangeListener in this case. Please see my code. How to switch it to WeakChangeListener.

    changeListener = new ChangeListener<Object[]>() {

        @Override
        public void changed(ObservableValue<? extends Object[]> observable, Object[] oldValue, Object[] newValue) {
            if (newValue != null && oldValue != null) {
                if (oldValue[21].equals(newValue[21])) {
                    if (newValue[updateBasedValues] != null) {
                        if (!newValue[updateBasedValues].equals(oldValue[updateBasedValues])) {
                            justUpdated = true;
                        }
                    }
                }
            }
        }

    };        
    itemProperty().addListener(changeListener);
like image 318
kingkong Avatar asked Dec 31 '25 02:12

kingkong


1 Answers

You need to keep a reference to the weak listener so that it is not garbage collected too soon. Read this very good discussion on the oracle forum : https://community.oracle.com/thread/2396063

I've written an adapter class "WeakAdapter" that you can use or extend. Example on how to use this class: Instead of writing

myBooleanProperty.addListener(new ChangeListener<Boolean> () {...});

use:

weak = new WeakAdapter();
weak.addChangeListener(myBooleanProperty, new ChangeListener<Boolean> (){});

Here is the code of class WeakAdapter:

public class WeakAdapter {

    ArrayList<Object> listenerRefs = new ArrayList<>();

    public WeakAdapter() {
    }

    public void dipose() {
        listenerRefs.clear();
    }

    public final <T> void remove(ChangeListener<T> listener) {
        listenerRefs.remove(listener);
    }

    public final <T> void addChangeListener(final ObservableValue observable, ChangeListener<T> listener) {
        listenerRefs.add(listener);
        observable.addListener(new WeakChangeListener<>(listener));
    }

    public final <T> WeakListChangeListener<T> addListChangeListener(ListChangeListener<T> listener) {
        listenerRefs.add(listener);
        return new WeakListChangeListener<>(listener);
    }

    public void addInvalidationListener(final Observable listened, InvalidationListener listener) {
        listenerRefs.add(listener);
        listened.addListener(new WeakInvalidationListener(listener));
    }

    public final void stringBind(final StringProperty propertyToUpdate, final StringExpression expressionToListen) {
        ChangeListener<String> listener = new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> ov, String t, String name) {
                propertyToUpdate.set(name);
            }
        };
        listenerRefs.add(listener);
        expressionToListen.addListener(new WeakChangeListener<>(listener));
        listener.changed(null, null, expressionToListen.get());
    }

    public final void booleanBind(final BooleanProperty propertyToUpdate, final BooleanExpression expressionToListen) {
        ChangeListener<Boolean> listener = new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean name) {
                propertyToUpdate.set(name);
            }
        };
        listenerRefs.add(listener);
        expressionToListen.addListener(new WeakChangeListener<>(listener));
        propertyToUpdate.set(expressionToListen.get());
    }
}
like image 104
Daniel Avatar answered Jan 02 '26 16:01

Daniel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!