Markus Weninger
Markus Weninger

Reputation: 12668

How to add multiple tab close event handlers to JavaFX Tab?

JavaFX's Tab class provides a setOnClosed method to add an event handler that is executed when the tab has been closed.

This works well when I only want to add a single event handler. What I haven't achieved yet is to add multiple event handlers, since calling setOnClosed a second time "overwrites" the event handler set on the first call.

In the following code example, only doSomethingIsExecuted is executed on tab close, yet I would like that all three event handlers are executed.

Tab tab = new Tab();
tab.setOnClosed(event -> doSomething());
tab.setOnClosed(event -> doSomethingElse());
tab.setOnClosed(event -> doSomethingIsExecuted());

Additional info: It is not possible to combine the three event handlers into one in my case, I really need a solution to add multiple event handlers.

Upvotes: 0

Views: 400

Answers (1)

fabian
fabian

Reputation: 82521

Use a handler that invokes multiple handlers form a list:

List<EventHandler<Event>> closedEventHandlers = new ArrayList<>();
tab.setOnClosed(event -> {
    for (Iterator<EventHandler<Event>> iterator = closedEventHandlers.iterator(); !event.isConsumed() && iterator.hasNext();) {
        iterator.next().handle(event);
    }
});

If you don't have a place add the elements to the list you could use a helper method that stores the the list in the properties of Tab:

public final class TabUtils {
    private TabUtils() {}

    private static final String TAB_CLOSED_HANDLERS_KEY = "TabUtils.CLOSED_EVENT.list";

    public static void addClosedHandler(Tab tab, EventHandler<Event> handler) {
        List<EventHandler<Event>> handlers = (List<EventHandler<Event>>) tab.getProperties().get(TAB_CLOSED_HANDLERS_KEY);
        if (handlers == null) {
            // create & store new handler list and register handler
            handlers = new ArrayList<>();
            tab.getProperties().Put(TAB_CLOSED_HANDLERS_KEY, handlers);
            tab.setOnClosed(event -> {
                for (Iterator<EventHandler<Event>> iterator = handlers.iterator(); !event.isConsumed() && iterator.hasNext();) {
                    iterator.next().handle(event);
                }
            });
        }
        handlers.add(handler);
    }

    public static void removeClosedHandler(Tab tab, EventHandler<Event> handler) {
        List<EventHandler<Event>> handlers = (List<EventHandler<Event>>) tab.getProperties().get(TAB_CLOSED_HANDLERS_KEY);
        if (handlers != null) {
            if (handlers.remove(handler) && handlers.isEmpty()) {
                // remove handler list and handler if there are no more handlers
                tab.getProperties().remove(TAB_CLOSED_HANDLERS_KEY);
                tab.setOnClosed(null);
            }
        }
    }
}

Upvotes: 2

Related Questions