如何使 Label 的高度与 JavaFX 中的字体大小相同?

How to make Label take same height as font size in JavaFX?

我把上标签的字号设置为24px。 我不知道在哪里可以检查元素的真实高度(如果在场景构建器中可能的话),但是在框的上部(在图像中指定)和下部有额外的 space。

我需要标签的高度等于字体大小。 我是说 FontSize = Gray space surrounded by blue markers height.

如何到达?

我遇到过类似的问题HTML/CSS。 在那里,对于大多数情况来说,不简单但有效的解决方案是负边距和 :before:after 伪元素。

JavaFX 现在有哪些解决方案?

复制

Repository

通过 Scene Builder 打开 resources/static/TasksOverview.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="640.0" prefWidth="320.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <HBox alignment="CENTER_LEFT">
         <children>
            <CheckBox mnemonicParsing="false" />
            <VBox>
               <children>
                  <Label style="-fx-font-size: 24px;" text="Wake up">
                     <VBox.margin>
                        <Insets />
                     </VBox.margin>
                  </Label>
                  <Label style="-fx-font-size: 14px;" text="... and fly. I need more text to test multiline mode." wrapText="true" />
               </children>
               <HBox.margin>
                  <Insets left="12.0" />
               </HBox.margin>
            </VBox>
         </children>
         <padding>
            <Insets left="12.0" right="12.0" />
         </padding>
      </HBox>
      <HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="10.0">
         <children>
            <CheckBox mnemonicParsing="false" />
            <VBox>
               <children>
                  <Label style="-fx-font-size: 24px;" text="Wash face">
                     <VBox.margin>
                        <Insets />
                     </VBox.margin>
                  </Label>
                  <Label style="-fx-font-size: 14px;" text="... with cold water." wrapText="true" />
               </children>
               <HBox.margin>
                  <Insets left="12.0" />
               </HBox.margin>
            </VBox>
         </children>
         <padding>
            <Insets left="12.0" right="12.0" />
         </padding>
      </HBox>
   </children>
</VBox>

只需设置添加负插图,它就会缩小标签上方的 space 例如:

<Insets top="-5.0"/>

完整的 FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="640.0" prefWidth="320.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <HBox alignment="CENTER_LEFT">
            <children>
                <CheckBox mnemonicParsing="false" />
                <VBox>
                    <children>
                        <Label style="-fx-font-size: 24px;" text="Wake up">
                            <VBox.margin>
                                <Insets top="-5.0"/>
                            </VBox.margin>
                        </Label>
                        <Label style="-fx-font-size: 14px;" text="... and fly. I need more text to test multiline mode." wrapText="true" />
                    </children>
                    <HBox.margin>
                        <Insets left="12.0" />
                    </HBox.margin>
                </VBox>
            </children>
            <padding>
                <Insets left="12.0" right="12.0" />
            </padding>
        </HBox>
        <HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="10.0">
            <children>
                <CheckBox mnemonicParsing="false" />
                <VBox>
                    <children>
                        <Label style="-fx-font-size: 24px;" text="Wash face">
                            <VBox.margin>
                                <Insets />
                            </VBox.margin>
                        </Label>
                        <Label style="-fx-font-size: 14px;" text="... with cold water." wrapText="true" />
                    </children>
                    <HBox.margin>
                        <Insets left="12.0" />
                    </HBox.margin>
                </VBox>
            </children>
            <padding>
                <Insets left="12.0" right="12.0" />
            </padding>
        </HBox>
    </children>
</VBox>

标签是“智能”控件,在“皮肤”代码中包括一些 in-built 填充之类的东西,以及文本和图形的各种对齐和间距选项,并支持通过动态调整大小省略文本。

如果您想更多地控制文本布局的方式,那么您可以使用原始文本节点而不是标签,然后在需要时自己进行一些额外的布局。当然,那样你会失去很多 in-built 功能(买家要小心......),但有时这可能就是你想要的。

例如,具有以下属性的文本节点:

  1. 字体大小为 24。
  2. 文本可视区域的顶部、左侧或右侧没有间距。
  3. 放置在 VBox 中时,文本可视区域下方 3 个像素的边距间距。

可以在FXML中定义如下:

<Text boundsType="VISUAL" text="Visual bounds != Logical bounds">
    <font>
        <Font size="24.0" />
    </font>
    <VBox.margin>
        <Insets bottom="3.0" />
    </VBox.margin>
</Text>

如果你在很多文本上使用这些东西,那么你可以在样式中设置很多值 sheet 而不是 FXML(这会更好)。除了说文本有一个未记录的 -fx-bounds-type css 属性外,我不会在这里描述如何做到这一点。

有时,与其使用文本节点,不如通过使用负插图之类的东西(这通常是我的首选...)来“破解”类似于马特的答案的标签可能更好。

小心,下面是深奥的讨论,准备无视吧;-)

关键部分是将 boundsType 设置为 VISUAL。默认情况下,文本的边界通常比您实际看到的多一点,这可以缓解对齐问题,因为这意味着字母“a”和字母“A”的边界是相同的。这种边界是默认的,称为逻辑边界。 VISUAL bounds 使这两个字母的边界不同,所以“a”的边界小于“A”的边界,这使得东西不会占用比绝对需要更多的space。

例如,使用带有 VISUAL 边界的文本而不是标签,可以去除示例屏幕截图中出现的文本周围的两组额外白色space。一组 whitespace 由 Label 控件的内部布局算法分配,另一组 whitespace 分配给 LOGICAL bounds.

通过应用适当的 CSS 样式sheet,可以在标签内将边界设置为 VISUAL,但如果您这样做,标签仍然不会缩小以仅适合 VISUAL 边界因为它似乎被编码为基于逻辑界限工作,至少我尝试的一些快速测试似乎表明了这一点。因此,在标签的文本中使用 VISUAL 边界似乎只会使其显示不正确(甚至可能被某些人归类为错误)。如果您在标签内设置带有文本的图形,它可能会起作用,但如果您这样做,标签对您没有多大作用,也可以直接使用文本节点(除非您使用的是像 TitledPane 这样的控件在标题中包含标签,在这种情况下您必须使用标签)。