如何让标签的高度与 JavaFX 中的字体大小相同?

Gur*_*ofu 3 javafx fxml scenebuilder

我将上标签的字体大小设置为 24px。我不知道在哪里可以检查元素的实际高度(如果在场景构建器中可能的话),但是盒子的上部(在图像中指定)和下部有额外的空间。

  • 行间距为0
  • 父 VBox 没有顶部填充。
  • 计算所有标签大小。

在此处输入图片说明

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

如何达到?

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

现在有哪些适用于 JavaFX 的解决方案?

再现

存储库

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>
Run Code Online (Sandbox Code Playgroud)

jew*_*sea 5

标签是“智能”控件,在“皮肤”代码中包括一些内置填充等内容,以及文本和图形的各种对齐和间距选项,并支持通过动态删除文本来调整大小。

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

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

  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>
Run Code Online (Sandbox Code Playgroud)

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

有时,与其使用 Text 节点,不如通过使用诸如负插图之类的东西来“破解”类似于 Matt 的答案的标签(这通常是我的首选选项......)。

小心,下面是深奥的讨论,准备好忽略它;-)

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

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

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