css - 如何动态更改 UI 中的字体大小以在 JavaFX 中始终保持相同的宽度?

标签 css user-interface javafx dynamic fxml

我想做的是使用 Scenebuilder 在 fxml 中创建一个标签,它会更新其字体大小以始终确保标签的内容大小相同。

一些背景信息是我正在使用一个最大化且不可调整大小的 AnchorPane

我不需要文本的高度相同——只是宽度相同。此外,我只想调整大小如果它太大而不适合。所以如果标签只有 1 个字母,我不希望它是一个巨大的单个字母。我只有初步的想法,下面是一些伪代码。谢谢!

lengthOfLabel = menuLabel.getText().length();

if(lengthOfLabel > numOfCharsThatCanFitInWidth){
    menuLabel.setStyle("-fx-font-size: " + (int) (someConstant/lengthOfLabel) + ";")
}

最佳答案

您可以使用临时 Text 对象来测量文本大小,如果不适合则缩放字体。像这样:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Main extends Application {

    //maximum width of the text/label
    private final double MAX_TEXT_WIDTH = 400;
    //default (nonscaled) font size of the text/label
    private final double defaultFontSize = 32;
    private final Font defaultFont = Font.font(defaultFontSize);

    @Override
    public void start(Stage primaryStage) {

        final TextField tf = new TextField("Label text goes here");

        final Label lbl = new Label();
        lbl.setFont(defaultFont);
        lbl.textProperty().addListener((observable, oldValue, newValue) -> {
            //create temp Text object with the same text as the label
            //and measure its width using default label font size
            Text tmpText = new Text(newValue);
            tmpText.setFont(defaultFont);

            double textWidth = tmpText.getLayoutBounds().getWidth();

            //check if text width is smaller than maximum width allowed
            if (textWidth <= MAX_TEXT_WIDTH) {
                lbl.setFont(defaultFont);
            } else {
                //and if it isn't, calculate new font size,
                // so that label text width matches MAX_TEXT_WIDTH
                double newFontSize = defaultFontSize * MAX_TEXT_WIDTH / textWidth;
                lbl.setFont(Font.font(defaultFont.getFamily(), newFontSize));
            }

        });
        lbl.textProperty().bind(tf.textProperty());

        final AnchorPane root = new AnchorPane(lbl, tf);
        AnchorPane.setLeftAnchor(tf, 0d);
        AnchorPane.setRightAnchor(tf, 0d);
        AnchorPane.setBottomAnchor(tf, 0d);


        primaryStage.setScene(new Scene(root, MAX_TEXT_WIDTH, 200));
        primaryStage.show();
    }
}

请注意,tmpText.getLayoutBounds() 返回不包含任何转换/效果的边界(如果需要这些,您必须将文本对象添加到临时场景并在 parent )。

Text fits Text fits, again Text scaled down

关于css - 如何动态更改 UI 中的字体大小以在 JavaFX 中始终保持相同的宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54495381/

相关文章:

html - 使用 mixins 制作网格

java - JFrame 不动

cocoa - Snow Leopard 上用于 QuickTimeX 的 UI 框架?

java - Android,不生成ActionBar

java - 如何使用 javafx 在工具提示中包装文本?

html - 表单输入边框半径无法正常工作

HTML 表格宽度不适合不同的列数

listview - 删除 JavaFX ListView 边框

css - 如何设置 prismjs 复制到剪贴板按钮的样式?

JavaFX - 需要通过初始化预填充字段,但不允许异常(exception)。有什么办法解决这个问题吗?