JavaFX TabPane: How to Listen for Selection Changes

I want to do some action when the user moves from one tab to another, since I created my form design using Scene Builder. I cannot use the one specified here (he used TabPaneBuilder )

I figured this code would work, but it doesn’t respond 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"); } } } ); 
+14
java listener javafx propertychangelistener
source share
4 answers

The correct way to use the change listener is:

 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 is the code in question not working? I think this is because your change listener is listening for changes in " selectionModel " instead of " selectedItem "


Finding when a tab has been added or removed is a bit more complicated:

 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() ) { // ... } } } ); 
+35
source share

Or in Java 8 using the lambda expression ....

 chatTabs.getSelectionModel().selectedItemProperty().addListener((ov, oldTab, newTab) -> { System.err.println("changed"); }); 
+12
source share

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

Please note that you must also use Tab.isSelected to properly respond to this tab or unselect 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 
+1
source share

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

 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 this

 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. }); 
0
source share

All Articles