This discussion is archived
7 Replies Latest reply: Feb 12, 2013 6:31 AM by 903182 RSS

How to restrict closing the tab in tabpane after clicking the close button.

SaiPradeepDandem Explorer
Currently Being Moderated
Hi all,
Greetings.
I am implementing a TabPane with different 'user form's in each Tab. And all the tabs are *'closable'*.
If the user enters some data in the form, and tries to close the tab without saving the form , i need to show a confirm dialogue box that the user should go ahead or not.
If he clicks cancel, the tab should not close.

But currently i am searching for a method something like 'setOnClosing' method for tab.
There is only tab.setOnClosed() method, which will call the event after closing the tab.

Some thing the code is like below.
tab.setOnClosed(new EventHandler<javafx.event.Event>() {
     @Override
     public void handle(javafx.event.Event e) {
        // TODO: Actions to be taken on close of tab.
           // Logic to show the confirm dialouge box.
           //  if YES - close the tab
           //  if NO - don't close the tab.
     }
});
But my logic is executing after closing the tab. (ofcourse, as it is on setOnClosed() ;) ). Can anyone tell me how to get control before closing the tab ?

Thanks in Advance.
Sai Pradeep Dandem.
  • 1. Re: How to restrict closing the tab in tabpane after clicking the close button.
    Narayan Pro
    Currently Being Moderated
    Hello Pradeep,

    You cannot do these restriction on Tab but you can do it from TabPane and MouseEvent somehow.
    I think you need to first get the corordinate of tab and test if the event of mouse occurs in that boundary then only dispatch your logic.
    I'm not sure this will work and my answer can't be totally correct. It's only the algorithm for your issue.
    You can follow this approach for your restriction of Tab Closing.
    <tabPane>.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>(){
         public void handle(MouseEvent t) {
              if(t.getEventType() == MouseEvent.MOUSE_RELEASED){
                             
                            //If the mouse x,y co ordinate is with in the tab bound then do this: {
                   if(/*<your business logic condition matches>*/){
                        //Just  let the close of tab happen or other things happen
                   }else{
                        t.consume();
                        //show your own dialog box;
                        //and do you own stuffs
                   }
                   //}
    
              }
         
         }
         
    });
    Thanks
    Narayan
  • 2. Re: How to restrict closing the tab in tabpane after clicking the close button.
    SaiPradeepDandem Explorer
    Currently Being Moderated
    Hi All,
    Finally I managed to get the handler before closing the tab pane. :)
    Though this is a bit weird work around, my requirement is fulfilled at-least.

    Let me explain the workaround I did.
    Tab tab = new Tab(title);
    tab.setClosable(false); // This line of code  makes sure that the “default” close button of the tab is not appeared.
    setClosableButton(tab);
    Then I am setting the custom close button as a graphic to the label ( Title of the tab), and aligning that graphic position to make an effect, that it is rendered exactly at the position of “Close” button.
    From this Custom Close Button, I am handling the events and if confirmed I am closing the tab manually, by calling the closeTab() method in the TabPaneBehavior class.

    Below is the code that is implemented as per the above logic.
            /**
          * Method to set the custom Closable Button to the given tab.
          * @param tab - Tab
          */
         private void setClosableButton(final Tab tab,final boolean closeCheck){
              final StackPane closeBtn = new StackPane(){
                   @Override
                   protected void layoutChildren() {
                        super.layoutChildren();
                        // Setting the orientation of graphic(button) to the right side.
                        ((Label)((LabelSkin)getParent()).getSkinnable()).setStyle("-fx-content-display:right;");
                   }
              };
              closeBtn.getStyleClass().setAll(new String[] { "tab-close-button" });
              closeBtn.setStyle("-fx-cursor:hand;");
              closeBtn.setPadding(new Insets(0,7,0,7));
              closeBtn.visibleProperty().bind(tab.selectedProperty());
              
              final EventHandler<ActionEvent> closeEvent = new EventHandler<ActionEvent>() {
                   @Override
                   public void handle(ActionEvent paramT) {
                        ((TabPaneSkin)TabPaneComponent.this.getSkin()).getBehavior().closeTab(tab);
                   }
              };
              
              // Handler for the close button.
              closeBtn.setOnMouseReleased(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent paramT) {
                        // My logic to handle the close event or not.
                                    if( logic satisfied){
                             closeEvent.handle(null);
                                    }else{
                                           // Dont close the tab.
                                    }
                        
                   }
              });
              
              // Showing the close button if the tab is selected.
              tab.selectedProperty().addListener(new ChangeListener<Boolean>() {
                   @Override
                   public void changed(ObservableValue<? extends Boolean> paramObservableValue,Boolean paramT1, Boolean isSelected) {
                        if(isSelected){
                             tab.setGraphic(closeBtn);
                        }else{
                             tab.setGraphic(null);
                        }
                   }
              });
         }
    There are some drawbacks in the above code. In practice, it is suggested not to use the classes (*LabelSkin* & TabPaneSkin) that are in com.sun.javafx package. But I couldn’t get a better solution other than using those classes. And another one is I could'nt set the actual graphic for tab, as i am already using that graphic property to show the close button.

    I would like to thank Narayan, for giving some inputs which has helped me to think and get the above solution. :)
  • 3. Re: How to restrict closing the tab in tabpane after clicking the close button.
    893064 Newbie
    Currently Being Moderated
    Hi,

    I was looking for the same thing and what you did is great.

    Anyhow, here is a call to the JavaFX Devs : PLEAAAAASSEEE add something like a beforeClose(...) method to the Tab. This should not be such a big of a deal and gives us an easy to use possibiltiy to hook in an do exactly what was requested here.

    Thanks and thumbs up on JavaFX in general.

    Cheers, Rob.

    (Its not very uncommon to check something - like save - before the Tab should be closed).
  • 4. Re: How to restrict closing the tab in tabpane after clicking the close button.
    jsmith Guru
    Currently Being Moderated
    @Rob best way to do make a feature or api request is via jira and then note a reference to the jira you create in the forum thread.
    http://javafx-jira.kenai.com
    https://forums.oracle.com/forums/ann.jspa?annID=1713
  • 5. Re: How to restrict closing the tab in tabpane after clicking the close button.
    838908 Newbie
    Currently Being Moderated
    Did a Jira ever get raised for this?
  • 6. Re: How to restrict closing the tab in tabpane after clicking the close button.
    jsmith Guru
    Currently Being Moderated
    I don't know, as there is no reference to it in the thread, I guess not.
  • 7. Re: How to restrict closing the tab in tabpane after clicking the close button.
    903182 Newbie
    Currently Being Moderated
    Seems to be possible in Version 8:

    http://javafx-jira.kenai.com/browse/RT-24088

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points