【问题标题】:setFont() method not working on label as expected javafxsetFont() 方法未按预期在标签上工作 javafx
【发布时间】:2016-11-02 19:46:06
【问题描述】:

我正在创建一个简短的 javafx 程序,其中包含一个带有一些文本的标签和一个按钮,该按钮应该将标签的字体更改为斜体。由于我使用的字体是自定义字体,因此无法直接调用new Font("human.ttf", FontPosture.ITALIC, 20),因为 javafx 无法将自定义字体转换为斜体或粗体。

所以我决定使用两个具有相同字体系列的不同字体文件,一个具有常规样式,另一个具有斜体样式。因此,当点击斜体按钮时,程序会加载斜体字体文件并将标签的字体设置为斜体字体。

但是当我尝试该程序时,单击斜体按钮后标签的字体不受影响。我努力寻找问题的根源并添加了几个打印语句。在这个过程中我发现问题是按钮的eventHandler中的setFont方法没有正常工作。由于打印语句,我还发现字体文件路径是正确的。因此,我无法找出我在代码中的错误。

这是 FontChanger 类:

public class FontChanger extends Application{

    private Label label;

    private Font font;

    public void start(Stage primaryStage){
        AnchorPane root = new AnchorPane();
        root.setPrefHeight(30);
        root.setPrefWidth(30);
        addLabel(root);
        addItalicButton(root);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.sizeToScene();
        primaryStage.show();
    }

    public void addLabel(AnchorPane root){
        label = new Label("Sample text");
        font = Font.loadFont(FontChanger.this.getClass().getResource("human.ttf").toExternalForm    (), 20);
        label.setFont(font);
        label.setLayoutX(10);
        label.setLayoutY(10);
        root.getChildren().add(label);
    }


    public void addItalicButton(AnchorPane root){
        Button italicButton = new Button("italic");
        italicButton.setLayoutX(10);
        italicButton.setLayoutY(35);
        italicButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                font = Font.loadFont(FontChanger.this.getClass().getResource("human_italic.ttf").toExternalForm(), 20);
                System.out.println(FontChanger.this.getClass().getResource("human_italic.ttf").to    ExternalForm());
                label.setFont(font);
            }
        });
        root.getChildren().add(italicButton);
    }

    public static void main(String[] args){
        launch(args);
    }
}

如果需要任何澄清,请告诉我。提前致谢。

【问题讨论】:

    标签: java javafx-8


    【解决方案1】:

    最后经过数小时的实验,我发现问题在于,每当标签或任何类似控件的字体已设置为自定义字体时,您无法再次将其设置为另一种自定义字体。我不知道为什么会发生这种情况。

    你不能这样做:

    public void setFont(){
        Font firstCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("firstCustomFont.ttf").toExternalForm(), 20);
        label.setFont(firstCustomFont);
        Font secondCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("secondCustomFont.ttf").toExternalForm(), 20);
        label.setFont(secondCustomFont);// this will not work
    }
    

    我还发现您可以在将标签的字体设置为自定义字体后将其设置为普通字体。如果它已经设置为本地字体,您也可以将字体设置为自定义字体。

    这两个例子都行:

    public void setFont(){
        Font customFont = Font.loadFont(FontChanger.this.getClass().getResource("customFont.ttf").toExternalForm(), 20);
        label.setFont(customFont);
        Font normalFont = Font.font(20);
        label.setFont(normalFont);// this will work
    }
    

    还有:

    public void setFont(){
        Font normalFont = Font.font(20);
        label.setFont(normalFont);
        Font customFont = Font.loadFont(FontChanger.this.getClass().getResource("customFont.ttf").toExternalForm(), 20);
        label.setFont(customFont);// this will work
    }
    

    所以我应用的技巧是我首先将标签的字体设置为本地字体,然后再次将字体设置为您要设置的自定义字体。

    类似这样的:

    public void setFont(){
        Font firstCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("firstCustomFont.ttf").toExternalForm(), 20);
        label.setFont(font);
        Font normalFont = Font.font(20);
        label.setFont(normalFont);
        Font secondCustomFont = Font.loadFont(FontChanger.this.getClass().getResource("secondCustomFont.ttf").toExternalForm(), 20);
        label.setFont(secondFont);// this will work
    }
    

    编辑: 出现这个问题是因为我使用的字体文件是同一个字体系列的编辑版本。因此,如果您有字体文件的常规和样式版本,然后您想将样式版本应用于已经设置为常规版本的文本,则此方法可以很好地工作。

    【讨论】:

    • 有趣:这看起来像一个错误。 Label.setFont 将委托给 fontProperty().set(...) 方法。如果提供的字体与当前字体相同(在.equals(...) 的意义上),则该方法变为无操作。 Font 定义.equals(...) 比较字体的名称和大小;因此,如果分配给自定义字体的名称相同,那么我认为这就是失败的原因。 firstCustomFont.getName()secondCustomFont.getName() 返回什么?
    • 是的,你是对的。它们返回相同的值。这是因为我使用的字体文件是同一个字体文件的编辑版本。所以这是我认为我没有考虑的领域。感谢您的意见。
    • 所以如果你能以某种方式在文件名中添加某种版本控制......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多