JavaFX TabPane: How to listen to selection changes
Asked Answered
V

4

24

I want to do some actions when user goes from one tab to another, since i made my form design with Scene Builder I cannot use code mentioned here (He used TabPaneBuilder class)

I guessed this code would work but it doesn't react to tab selection changes.

@FXML
protected TabPane chatTabs;
.
.    
.
chatTabs.selectionModelProperty().addListener(
    new ChangeListener<SingleSelectionModel<Tab>> {
            @Override
            public void changed(ObservableValue<? extends SingleSelectionModel<Tab>> ov, SingleSelectionModel<Tab> t, SingleSelectionModel<Tab> t1) {
                System.err.println("changed");
            }
        }
    }
);
Vizza answered 8/7, 2013 at 9:3 Comment(0)
V
51

The right way to use change listener is this:

chatTabs.getSelectionModel().selectedItemProperty().addListener(
    new ChangeListener<Tab>() {
        @Override
        public void changed(ObservableValue<? extends Tab> ov, Tab t, Tab t1) {
            System.out.println("Tab Selection changed");
        }
    }
);

Why code in question didn't work? I guess its because your change listener listens to changes in "selectionModel" instead of "selectedItem"


Finding out when a tab has been added or removed is a little trickier:

tabs.addListener( (Change<? extends Tab> change) -> {
  while( change.next() ) {
    if( change.wasAdded() ) {
      for( final Tab tab : change.getAddedSubList() ) {
        System.out.println( "Tab Added: " + tab );
      }
    } else if( change.wasRemoved() ) {
      // ...
    }
  }
} );
Vizza answered 8/7, 2013 at 9:17 Comment(0)
R
17

Or in Java 8 using lambda expression....

chatTabs.getSelectionModel().selectedItemProperty().addListener((ov, oldTab, newTab) -> {
        System.err.println("changed");
    });
Ranaerancagua answered 4/10, 2015 at 8:20 Comment(0)
H
6

I think a much better and more natural approach is using Tab.setOnSelectionChanged. Here's a complete little program that implements that approach. You can see a MUCH more complete example here: http://sandsduchon.org/duchon/cs335/fx020.html

Note that you should also use Tab.isSelected to react correctly to selecting this tab or unselecting that this tab.

import javafx.application.Application; // FX base, requires start(Stage)
import javafx.stage.Stage;             // required by start (Stage)
import javafx.scene.Scene;             // no scene --> no display

import javafx.scene.control.TabPane;
import javafx.scene.control.Tab;

public class TabDemo extends Application {

   public void start (Stage stage) {
      TabPane tabPane = new TabPane ();

      Tab tba = new Tab ("one");
      Tab tbb = new Tab ("two");

      tabPane.getTabs().addAll (tba, tbb);

      tba.setOnSelectionChanged (e -> 
        System.out.println (
           tba.isSelected()?
           "a selected":
           "a unselected"
        )
      );

      Scene scene = new Scene (tabPane, 200, 50);
      stage.setScene (scene);
      stage.setTitle ("A Study of tab listeners");
      stage.show ();
   } // end start

} // end class TabDemo
Hochheimer answered 23/8, 2018 at 1:51 Comment(1)
nothing inherently better in registering the handler: on the contrary (but arguable :) it might be considered worse than a changeListener on the selected item because with the former there's more coupling to outer context (the reference to tba plus check for actual selection state), while both old/new tabs are passed into the changeListener - and a not-null new is guaranteed to be selected.Cavit
D
0

In addition to MJafar Mash answer above, you can use "selectedIndexProperty()" to get the index of the selected tab instead of "selectedItemProperty()" which gets the selected tab itself.

chatTabs.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number> (){
     @Override
     public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
           int selectedIndex = newValue.intValue();
           //where index of the first tab is 0, while that of the second tab is 1 and so on.
     }
 });

And this is the lambda expression version of it

chartTabs.getSelectionModel().selectedIndexProperty().addListener( (observable, oldValue, newValue) -> {
       int selectedIndex = newValue.intValue();
       //where index of the first tab is 0, while that of the second tab is 1 and so on.
});
Deleterious answered 9/6, 2019 at 15:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.