Home > OS >  javafx TabPane setSelection doesn't switch the tab
javafx TabPane setSelection doesn't switch the tab

Time:07-02

I want to control the TabPane and switch tabs with a Canvas, basically hide the tab headers and use canvas instead, the canvas displays different "Devices" and when user click on the device, the TabPane switch to show the content of that device.

fun canvasFlow_Click(mouseEvent: MouseEvent) {
    val d = flowPresenter.click(mouseEvent)
    if (d != null) {
        flowPresenter.select(d)
        logger.info("switch to ${d.position}")
        tab.selectionModel.clearSelection()
        tab.selectionModel.select(d.position)
    }
}

Why select doesn't work? I don't see tab content changed. from log, I see "switch to 1", "switch to 2" correctly, just the tab doesn't switch! Why?

CodePudding user response:

Note: this is plain javafx and might not be the exact solution in your case (hard to tell without example) - but actually I can reproduce the described behavior.

The problem seems to be calling clearSelection: TabPane with tabs should have exactly one selected tab - which is not specified. But every internal collaborator (skin, header, listener) goes to great lengths to guarantee that constraint - this assumption was wrong, in fact the skin gets confused if the selection changes to empty - the previously selected content is not removed. Might be a bug, either don't allow the selectionModel to be empty or improve the skin to cope with it (wondering how that would be supposed to look - hide the content?)

Anyway, here the solution is to not call that method before manually selecting a tab. There's no need to do so anyway, it's a SingleSelectionModel so takes care of allowing at most one item selected.

An example: un/comment the clearSelection and see how the content is not/ correctly updated with/out the call.

public class TabPaneSelection extends Application {

    private Parent createContent() {

        TabPane pane = new TabPane();
        HBox headers = new HBox();

        for (int i = 0; i < 3; i  ) {
            int index = i;
            Tab tab = new Tab("header "   i, new Label("content "   i));
            pane.getTabs().add(tab);
            Button button = new Button(tab.getText());
            button.setOnAction(e -> {
                // do __not__ clear selection
                //pane.getSelectionModel().clearSelection();
                pane.getSelectionModel().select(index);
            });
            headers.getChildren().add(button);
        }

        BorderPane content = new BorderPane(pane);
        content.setTop(headers);
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent(), 400, 300));
        //stage.setTitle(FXUtils.fxVersion());
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}
  • Related