-1

I have been reading this stackoverflow post. And they say tabPane.getTabs().remove(tab) will not trigger the listener on the event closing the tab which makes sense.

Therefore, I have applied their solution to my problem (I understand the principle, but not really the code), but my listener will never get called. Neither tabPane.getTabs().remove(tab) nor closeTab(tab) with the method closeTab defined like so:

private void closeTab(Tab tab) {
        EventHandler<Event> handler = tab.getOnClosed();
        if (null != handler) {
            handler.handle(null);
        } else {
            tab.getTabPane().getTabs().remove(tab);
        }
    }

call my listener. My listener is however called when I do close the tab with the mouse.

Here is my listener:

private static void addListenerOnClosingTab(Tab tab) {
        tab.setOnCloseRequest(new EventHandler<Event>()
        {
            @Override
            public void handle(Event arg0)
            {
                Util.loggerControllerDiagram.info("Tab " + tab.getText() + " closed.");
            }
        });
    }
  • 2
    [mcve] please, demonstrating why you are using such an unusual construct - a onClose handler is notified automatically, if not null – kleopatra Apr 23 '22 at 12:50
  • 1
    If you want to respond to a tab being closed either by the user, or programmatically, why not just add a listener to the tab pane’s list of tabs? – James_D Apr 23 '22 at 13:45
  • Not sure what unusual construct you're talking about. I've just copied the other stackoverflow answer? – FluidMechanics Potential Flows Apr 23 '22 at 18:13
  • I don't really understand what you mean by a listener to the tab pane's list of tabs? sorry I'm a total beginner in java & javaFX. – FluidMechanics Potential Flows Apr 23 '22 at 18:14
  • 1
    @FluidMechanicsPotentialFlows `tabPane.getTabs()` returns an observable list of the tabs in the tab pane. Add a `ListChangeListener` to it. I don’t really know how to say it more simply than that. – James_D Apr 23 '22 at 20:01

2 Answers2

1

None of these approaches (in other current answers in this post, or in the original post you linked) really make sense to me. It's possible I am not understanding what you are trying to do.

If you want to respond to a tab being removed, whether it is removed by the user clicking the tab close button, or programmatically by manipulating the tab pane's list of tabs, the usual approach would be to register a listener with the list of tabs:

private TabPane tabPane ;

// ...

tabPane.getTabs().addListener((Change<? extends Tab> c) -> {
    while (c.next()) {
        if (c.wasRemoved()) {
            for (Tab tab : c.getRemoved()) {
                System.out.println("Tab " + tab.getText() + " closed.");
            }
        }
    }
});
James_D
  • 201,275
  • 16
  • 291
  • 322
  • I understand your idea but I have this error: https://i.imgur.com/Z00yKgF.png. I guess the difference with the other posts/comments is that the listener is not on the list but that there is a EventHandler on each of the tabs? Still not sure what handler.handle does though. So if I can make your solution work, I'll be more satisfied as it is more understandable. – FluidMechanics Potential Flows Apr 24 '22 at 09:46
  • @FluidMechanicsPotentialFlows It should have been `c.next()` (I edited the code to fix it). – James_D Apr 24 '22 at 13:28
-1

You might want to use getOnCloseRequest instead of getOnClosed in your method closeTab:

EventHandler<Event> handler = tab.getOnCloseRequest();
handler.handle(null);
tab.getTabPane().getTabs().remove(tab);