更新时间: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).