在JavaFX中绑定字体大小?

Tac*_*nut 8 java data-binding user-interface fonts javafx

我想让我的申请流畅.但是,当我将窗口放大时,与UI元素相比,字体看起来很小.最终,当我调整窗口大小时,我希望文本的大小变大或变小.我知道理论上我可以用style属性来做这个,但是在某些情况下我已经将该属性绑定到了其他东西.

我知道还有的"fontProperty"的方法,但我没有将其绑定到,因为我无法弄清楚如何创建一个同步的大小动态OBJECTPROPERTY.我该怎么办?

编辑:为了避免混淆,我试图根据其他因素改变字体大小,而不是相反.

bri*_*ian 13

只需将所有想要字体大小的内容放在容器中,然后设置该样式或使用绑定(如果需要).

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FontBind extends Application {

    private DoubleProperty fontSize = new SimpleDoubleProperty(10);
    private IntegerProperty blues = new SimpleIntegerProperty(50);

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button("click me, I change color");
        btn.setOnAction((evt)->{blues.set(blues.get()+20);});//max?
        Label lbl = new Label("I'm a label");
        TextArea ta = new TextArea("Lots of text can be typed\nand even number 1234567890");
        HBox hbox = new HBox(new Label("I never change"));
        VBox child = new VBox(btn, lbl, ta);
        VBox root = new VBox(child, hbox);
        Scene scene = new Scene(root, 300, 250);

        fontSize.bind(scene.widthProperty().add(scene.heightProperty()).divide(50));
        child.styleProperty().bind(Bindings.concat("-fx-font-size: ", fontSize.asString(), ";"
                                                  ,"-fx-base: rgb(100,100,",blues.asString(),");"));

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}
Run Code Online (Sandbox Code Playgroud)

我不确定你的样式已经绑定了什么,但是你可以在样式字符串中设置多个css值.


jew*_*sea 9

设置.root -fx-font-size

  1. 为您的应用程序创建自定义样式表.
  2. 在sylesheet .root选择器中,设置-fx-font-size为所需的值:

    .root {-fx-font-size:40px; }

为什么会这样

这是因为:

  1. 所有默认控件都基于em单位(基于默认字体大小).
  2. -fx-font-size是一种继承的风格.
  3. 一切都从根源继承.

执行此操作后,所有控件(及其中的文本)将自动调整大小以适合您指定的任何字体大小.

相关样本

相关信息

em是一个非特定于JavaFX的通用单元,em单元也用于HTML CSS.如果有兴趣,您可以阅读有关em单位与其他单位更广泛讨论.

通过表达式绑定在FXML中使用em单位

只需设置默认字体大小,您就可以获得所需位置的大约90%,但不一定是通用修复,因为某些布局单元可能未指定使用em单位.大多数情况下,这不是一个真正的问题,但如果是在你的情况下,你也可以应用Oracle开发人员邮件列表帖子中描述的机制,这似乎有效,但有点笨拙.

如何使用表达式绑定.

对于35em x 25em,您可以写:

prefWidth="${35*u.em}" prefHeight="${25*u.em}"
Run Code Online (Sandbox Code Playgroud)

它不是100%简洁,但也许可以通过.

这些大小调整表达式在场景构建器1.1中工作,这很好.


下面是一个使用Rectangle存储fxml文件的宽度和高度修饰符的示例.

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

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>

<StackPane xmlns:fx="http://javafx.com/fxml">
<fx:define>
  <Rectangle fx:id="s" width="13" height="13"/>
</fx:define>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="${22 * s.width}" prefWidth="${14 * s.height}">
  <children>
    <Button layoutX="${4 * s.width}" layoutY="${ 5 * s.height}" prefWidth="${6 * s.width}" text="Top" />
    <Button layoutX="${4 * s.width}" layoutY="${10 * s.height}" prefWidth="${6 * s.width}" text="Middle" />
    <Button layoutX="${4 * s.width}" layoutY="${15 * s.height}" prefWidth="${6 * s.width}" text="Bottom" />
  </children>
</AnchorPane>
</StackPane>
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建自己的单元类并在大小调整表达式中使用它,例如:

package org.jewelsea.measure;

public class Measurement {
  private double em;
  public  void   setEm(double em) { this.em = em; }
  public  double getEm()          { return em; }
}

. . .

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

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.jewelsea.measure.Measurement?>
<?scenebuilder-classpath-element .?>

<StackPane xmlns:fx="http://javafx.com/fxml">
  <fx:define>
    <Measurement fx:id="u" em="26.0" />
  </fx:define>
  <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="${22*u.em}" prefWidth="${14*u.em}">
    <children>
      <Button layoutX="${4*u.em}" layoutY="${ 5*u.em}" prefWidth="${6*u.em}" text="Top" />
      <Button layoutX="${4*u.em}" layoutY="${10*u.em}" prefWidth="${6*u.em}" text="Middle" />
      <Button layoutX="${4*u.em}" layoutY="${15*u.em}" prefWidth="${6*u.em}" text="Bottom" />
    </children>
  </AnchorPane>
</StackPane>
Run Code Online (Sandbox Code Playgroud)

  • 你是JavaFX之神,JewelSea.我已经将这个答案用于一个完全不相关的问题.既然你在这个项目上帮了我很多,我就会继续把你带到学分中.现在,如果我可以调整字体大小,它应该允许每个人在启动画面上清楚地看到你的名字:D.感谢你的帮助! (5认同)

小智 6

有一个最简单且合适的方法将字体大小与容器大小绑定,以使其具有响应式字体缩放效果。

bind(Bindings.concat("-fx-font-size: "是一个不错的选择,但是当您调整窗口大小时,它似乎很慢,我认为这不是解决问题的正确方法。

您可以声明 FontProperty 并将此 FontProperty 绑定到组件(Label、Text 等),最后创建一个事件以根据我们的设计将大小与 FontProperty 大小绑定:

private Label textTracking = new Label();
private ObjectProperty<Font> fontTracking = new SimpleObjectProperty<Font>(Font.getDefault());
Run Code Online (Sandbox Code Playgroud)

然后在构造函数或某些 init 方法中,您可以将对象的字体属性与我们的动态字体绑定:

textTracking.fontProperty().bind(fontTracking);
Run Code Online (Sandbox Code Playgroud)

最后,您需要将包装容器更改大小与动态字体大小绑定:

    widthProperty().addListener(new ChangeListener<Number>()
    {
        @Override
        public void changed(ObservableValue<? extends Number> observableValue, Number oldWidth, Number newWidth)
        {
            fontTracking.set(Font.font(newWidth.doubleValue() / 4));
        }
    });
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,动态字体调整非常流畅和快速,甚至超过bind(Bindings.concat("-fx-font-size: "方法。