在 FXML 中填充 TabPane 的内容,而不是选项卡栏
Padding in FXML the content of a TabPane, but not the tab bar
我正在寻找一种优雅的方式来为 TabPane 设置填充,但不填充标签栏:
<TabPane>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Tab text="red">
<Rectangle fill="RED" width="200" height="200" />
</Tab>
<Tab text="blue">
<Rectangle fill="BLUE" width="200" height="200" />
</Tab>
</TabPane>
给出:
然而,
<TabPane>
<Tab text="red">
<VBox>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Rectangle fill="RED" width="200" height="200" />
</VBox>
</Tab>
<Tab text="blue">
<VBox>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Rectangle fill="BLUE" width="200" height="200" />
</VBox>
</Tab>
</TabPane>
给出:
这正是我想要的,但是我想简化 FXML 结构,主要是通过重构 <padding>
元素,以便它在一个地方声明(更短且不重复的代码)而不是在每个选项卡中窗格的。
那么有什么办法可以实现吗?还是我坚持使用重复的 <padding>
元素?我更喜欢 FXML 解决方案,但如果没有办法,一个 Java 也可以。
一句话:没有
TabPane
中的每个 Tab
接受一个 Node
因为它是 contentProperty
。内容本身不是 Region
,因此不能对其应用 Insets
或填充。 TabPane
本身不包含允许您一次为所有子 Tabs
的内容设置样式的方法。
您必须先将某种容器添加到 Tab
才能应用填充。所以你问题中的第二种方法是完成你想要做的事情的最简单方法。
解决方法
虽然这不能用 FXML 完成,但您可以使用 Java 循环在加载场景后向所有 Tab
对象添加相同的填充:
Insets insets = new Insets(10);
for (Tab tab : tabPane.getTabs()) {
((VBox) tab.getContent()).setPadding(insets);
}
当然,这假定您使用 VBox
作为所有选项卡的内容。
编辑:我更新了答案以使用下面 fabian 评论中的 CSS 选择器。
您可以在单独的 css 文件中为大多数 JavaFX 场景图对象设置填充。您需要将 link css 文件添加到我将在下面显示的 FXML 文件。 css 文件和 FXML 文件需要位于同一目录中,否则您将不得不编辑 value="..."
标签。
style.css
.tab-pane > .tab-content-area > * {
-fx-padding: 10 10 10 10;
}
这会为恰好位于 Tab
某处的所有 VBox
设置填充(无论在层次结构中有多深)
main.fxml
<TabPane>
<Tab text="red">
<VBox>
<Rectangle fill="RED" width="200" height="200" />
</VBox>
</Tab>
<Tab text="blue">
<VBox>
<Rectangle fill="BLUE" width="200" height="200" />
</VBox>
</Tab>
<stylesheets>
<URL value="@style.css" />
</stylesheets>
</TabPane>
我正在寻找一种优雅的方式来为 TabPane 设置填充,但不填充标签栏:
<TabPane>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Tab text="red">
<Rectangle fill="RED" width="200" height="200" />
</Tab>
<Tab text="blue">
<Rectangle fill="BLUE" width="200" height="200" />
</Tab>
</TabPane>
给出:
然而,
<TabPane>
<Tab text="red">
<VBox>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Rectangle fill="RED" width="200" height="200" />
</VBox>
</Tab>
<Tab text="blue">
<VBox>
<padding>
<Insets top="10" bottom="10" right="10" left="10" />
</padding>
<Rectangle fill="BLUE" width="200" height="200" />
</VBox>
</Tab>
</TabPane>
给出:
这正是我想要的,但是我想简化 FXML 结构,主要是通过重构 <padding>
元素,以便它在一个地方声明(更短且不重复的代码)而不是在每个选项卡中窗格的。
那么有什么办法可以实现吗?还是我坚持使用重复的 <padding>
元素?我更喜欢 FXML 解决方案,但如果没有办法,一个 Java 也可以。
一句话:没有
TabPane
中的每个 Tab
接受一个 Node
因为它是 contentProperty
。内容本身不是 Region
,因此不能对其应用 Insets
或填充。 TabPane
本身不包含允许您一次为所有子 Tabs
的内容设置样式的方法。
您必须先将某种容器添加到 Tab
才能应用填充。所以你问题中的第二种方法是完成你想要做的事情的最简单方法。
解决方法
虽然这不能用 FXML 完成,但您可以使用 Java 循环在加载场景后向所有 Tab
对象添加相同的填充:
Insets insets = new Insets(10);
for (Tab tab : tabPane.getTabs()) {
((VBox) tab.getContent()).setPadding(insets);
}
当然,这假定您使用 VBox
作为所有选项卡的内容。
编辑:我更新了答案以使用下面 fabian 评论中的 CSS 选择器。
您可以在单独的 css 文件中为大多数 JavaFX 场景图对象设置填充。您需要将 link css 文件添加到我将在下面显示的 FXML 文件。 css 文件和 FXML 文件需要位于同一目录中,否则您将不得不编辑 value="..."
标签。
style.css
.tab-pane > .tab-content-area > * {
-fx-padding: 10 10 10 10;
}
这会为恰好位于 Tab
某处的所有 VBox
设置填充(无论在层次结构中有多深)
main.fxml
<TabPane>
<Tab text="red">
<VBox>
<Rectangle fill="RED" width="200" height="200" />
</VBox>
</Tab>
<Tab text="blue">
<VBox>
<Rectangle fill="BLUE" width="200" height="200" />
</VBox>
</Tab>
<stylesheets>
<URL value="@style.css" />
</stylesheets>
</TabPane>