I want to cancel the tab change when a tab is clicked in my TabPane. I want to change tabs manually, not by user clicks on tabs.
How can I do that? Thanks in advance.
I want to cancel the tab change when a tab is clicked in my TabPane. I want to change tabs manually, not by user clicks on tabs.
How can I do that? Thanks in advance.
You could use event filter(s) to block the events you don't want tab header area to receive. The following code blocks the MOUSE_PRESSED
event responsible for changing the tabs on a click. Any click inside the content area is not blocked.
@Override
public void start(Stage stage) throws IOException {
Button btn = new Button("Click");
TabPane tp = new TabPane(new Tab("tab1", new StackPane(btn)), new Tab("tab2"));
btn.setOnAction(event-> {
tp.getSelectionModel().select(1); // change tab programmatically
});
tp.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
Node n = event.getPickResult().getIntersectedNode();
boolean outsideContentArea = true;
// iterate from node actually clicked to the TabPane
// and look for the content area
while (outsideContentArea && (n != tp)) {
if (n.getStyleClass().contains("tab-content-area")) {
outsideContentArea = false;
}
n = n.getParent();
}
if (outsideContentArea) {
// stop event propagation to any part
// of the TabPane outside the content area
event.consume();
}
});
Scene scene = new Scene(tp, 300, 300);
stage.setScene(scene);
stage.show();
}
If you want this type of flow you can do this by hiding the tabs so that they cannot be clicked on and then adding buttons to iterate through each tab
You will need the line below to hide the tabs
tabPane.setStyle("-fx-tab-max-height: -2;");//You can still see tabs at -1 not sure why
Note if you want to hide the header space(as seen in my application below) you need to do it though css and you can ignore the above line
.tab-pane {
-fx-tab-max-height: 0 ;
}
.tab-pane .tab-header-area {
visibility: hidden ;
}
and you will also need to look at how the buttons are setup to get to the next tab and previous tab as I am not sure what your application will look like I just did it with buttons but you can use the same action to move thought he tabs
Button buttonPlus = new Button("+");
buttonPlus.setOnAction(event -> {
int selectedIndex = tabPane.getSelectionModel().getSelectedIndex();
if(selectedIndex<tabPane.getTabs().size()-1)
tabPane.getSelectionModel().select(++selectedIndex);
});
Button buttonMinus = new Button("-");
buttonMinus.setOnAction(event -> {
int selectedIndex = tabPane.getSelectionModel().getSelectedIndex();
if(selectedIndex>0)
tabPane.getSelectionModel().select(--selectedIndex);
});
Also just as a heads up you can change tabs by passing an index like so tabPane.getSelectionModel().select(index);
or by passing a specific tab like so tabPane.getSelectionModel().select(tab);
Once these have been created and added to the scene you will easily be able to click through each tab
Check out my application below let me know if you have any questions
public class Main extends Application {
@Override
public void start(Stage stage) {
TabPane tabPane = new TabPane();
tabPane.setStyle("-fx-tab-max-height: -2;");//You can still see tabs at -1
createNewTab(tabPane);
createNewTab(tabPane);
createNewTab(tabPane);
stage.setScene(new Scene(tabPane));
stage.show();
}
private void createNewTab(TabPane tabPane){
Tab tab = new Tab();
tab.setClosable(false);
addNodesToTab(tabPane, tab);
tabPane.getTabs().add(tab);
}
private void addNodesToTab(TabPane tabPane, Tab tab){
Button buttonPlus = new Button("+");
buttonPlus.setOnAction(event -> {
int selectedIndex = tabPane.getSelectionModel().getSelectedIndex();
if(selectedIndex<tabPane.getTabs().size()-1)
tabPane.getSelectionModel().select(++selectedIndex);
});
Button buttonMinus = new Button("-");
buttonMinus.setOnAction(event -> {
int selectedIndex = tabPane.getSelectionModel().getSelectedIndex();
if(selectedIndex>0)
tabPane.getSelectionModel().select(--selectedIndex);
});
tab.setContent(new VBox(new Label("Tab:"+tabPane.getTabs().size()),buttonPlus, buttonMinus));
}
}