Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispose Method of JavaFX Controls [closed]

Tags:

java

javafx

I have a control that should react to some kinds of events, and therefore adds itself to a listener list in the constructor. Of course it should remove itself as well, but while Swing and RCP have dispose() methods, I can't seem to find any in JavaFx.

public class MyTable extends TableView implements MyListener {

public MyTable () {
    Events.addListener(this);
}

public disposeOrSomething() {
    Events.removeListener(this);
}

// actual implementation of MyListener 

}

Don't get hung up on the static Events class, thought. It does not matter to me if the control adds itself to something static or not. What is important: there are two parts of an application that are not connected except for a general event system. So when the listening part vanishes (e.g. the window gets closed) of course the listener should be disposed.

Up until know, when the listener was directly connected to the life cycle of the control, the control registered it. But now in JavaFX that won't work, and due to loosely coupled FXML files I can't see anyone else who has the necessary information (the control and the "window close event") either.

So what is a good way to clean up after controls when they are no longer used?

like image 811
Steffi S. Avatar asked Dec 30 '25 11:12

Steffi S.


1 Answers

As said before, I recommend not using a global event bus and, as suggested by @Puce, not registering listeners on anything else than encapsulated objects.

Anyway, here is a way to automatically subscribe to events only when a certain Node is showing (i.e. automatically unsubscribe when the node is removed from the scene or the window is closed). This solution makes use of ReactFX, namely the helper EventStream#conditionOnShowing method.

Since you didn't provide the signature of MyListener, I will assume this signature:

@FunctionalInterface
interface MyListener {
    void handle(MyEvent event);
}

import org.reactfx.EventStream;
import org.reactfx.EventStreamBase;
import org.reactfx.Subscription;

public class MyTable extends TableView {
    public MyTable () {

        // Since you are using some custom event dispatching mechanism,
        // the first step is to convert that into a ReactFX EventStream.
        EventStream<MyEvent> events = new EventStreamBase<MyEvent>() {
            @Override protected Subscription observeInputs() {
                MyListener l = event -> notifyObservers(event);
                Events.addListener(l);
                return () -> Events.removeListener(l);
            }
        };

        // Now the interesting part: events will not be observed whenever
        // this MyTable is not part of a showing Window.
        events.conditionOnShowing(this).subscribe(event -> this.handleEvent(Event));
    }

    private void handleEvent(MyEvent) {
        /* ... */
    }
}
like image 120
Tomas Mikula Avatar answered Jan 02 '26 01:01

Tomas Mikula



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!