且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Javafx TabPane有多行标签

更新时间:2023-12-04 13:05:28

TabPane 的标题页区域基本上是 StackPane ,因此我认为创建两行标签而不是一行非常容易。

The tab header area for TabPane is basically a StackPane, therefore I think it is not so easy to create two rows of tabs instead of one.

我的想法是隐藏 TabPane的原始标签并放入一组 ToggleButton 对象a ToggleGroup 然后用选择的选项卡绑定选择的切换。

My idea is to hide the original tabs of your TabPane and put a set of ToggleButton objects in a ToggleGroup then bind the selection of toggles with the selection of tabs.

这样你可以将标签添加到你想要的任何容器中(流量,网格等)。

This way you could add the "Tabs" into any container you want (flow, grid, etc).

真正的最小样本:

Main.java

public class Main extends Application {

    TabPane tabPane;
    private ToggleGroup toggleGroup;

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();
        Scene scene = new Scene(root, 700, 400, Color.WHITE);

        primaryStage.setTitle("Tabs Test");

        toggleGroup = new ToggleGroup();
        toggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {

            @Override
            public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
                if (newValue == null)
                    toggleGroup.selectToggle(oldValue);
                else
                    tabPane.getSelectionModel().select((Tab) newValue.getUserData());
            }
        });

        tabPane = new TabPane();
        tabPane.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

        VBox vboxToggleOuterContainer = new VBox();
        HBox hboxToggleFirstRow = new HBox();
        HBox hboxToggleSecondRow = new HBox();

        vboxToggleOuterContainer.getChildren().addAll(hboxToggleFirstRow, hboxToggleSecondRow);

        for (int i = 0; i < 20; i++) {
            Tab tab = new Tab();
            tab.setText("Tab " + i);
            HBox hbox = new HBox();
            hbox.getChildren().add(new Label("Tab " + i));
            tab.setContent(hbox);
            tabPane.getTabs().add(tab);

            ToggleButton tb = new ToggleButton("Tab" + i);
            tb.setToggleGroup(toggleGroup);
            tb.setUserData(tab);

            if (i < 10)
                hboxToggleFirstRow.getChildren().add(tb);
            else
                hboxToggleSecondRow.getChildren().add(tb);
        }

        toggleGroup.selectToggle(toggleGroup.getToggles().get(0));

        VBox vbox = new VBox();
        vbox.getChildren().addAll(vboxToggleOuterContainer, tabPane);
        vbox.fillWidthProperty().set(true);
        root.getChildren().add(vbox);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

application.css

.tab-pane {
    -fx-skin: "com.sun.javafx.scene.control.skin.TabPaneSkin";
    -fx-tab-min-height: 0;  
    -fx-tab-max-height: 0; 
}

.tab-pane .tab-header-area {
    -fx-padding: 0 0 0 0; 
}

.tab-pane .tab-header-area .headers-region .tab {

    -fx-padding: 0 0 1 0;
}

这个例子真的很小,只是显示方法,你可以改进CSS让控制更加花哨(如果你愿意,我也可以更新它,如果我有时间的话)。

The example is really minimal, just shows the approach, you can improve the CSS to have the control much more fancy (or if you want I can also update it if I will have time).