在JavaFX中绑定字体大小?

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

我知道有“fontProperty”方法,但我没有任何东西可以绑定它,因为我无法弄清楚如何创建一个具有同步大小的动态ObjectProperty。 我该怎么办?

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

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

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); } } 

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

设置.root -fx-font-size

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

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

为什么会这样

这是因为:

  1. 所有默认控件都基于em单位(基于默认字体大小)。
  2. -fx-font-size是一种inheritance的样式。
  3. 一切都从根inheritance。

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

相关样本

  • javafx自动resize和按钮填充

相关信息

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

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

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

如何使用表达式绑定。

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

 prefWidth="${35*u.em}" prefHeight="${25*u.em}" 

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

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


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

                 

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

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

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

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

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

 private Label textTracking = new Label(); private ObjectProperty fontTracking = new SimpleObjectProperty(Font.getDefault()); 

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

 textTracking.fontProperty().bind(fontTracking); 

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

  widthProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observableValue, Number oldWidth, Number newWidth) { fontTracking.set(Font.font(newWidth.doubleValue() / 4)); } }); 

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

我有类似的问题并以这种方式解决了它:

  1. 在CSS和FXML文件中,我以相对的方式定义了所有字体大小,仅使用“em”而不是“%”或“px”
  2. 在主窗口的控制器中,我将主窗格的样式属性中的double值绑定到某个场景大小属性(例如,对角线长度的粗略近似)

它的工作原理是因为设置到主窗格的样式将影响已在FXML中定义的所有节点的修饰符。 已经具有样式类的节点也会受到影响,因为新样式在级联样式表中是另外的样式顶层。

此解决方案的主要优点是在单个位置处理字体大小缩放系数。 因此,您不必找到具有Font属性的每个节点来使其工作。

示例文件:

styles.css的

 .label { -fx-font-size: 1.1em; } .title { -fx-font-size: 1.5em; -fx-font-weight: bold; } 

main.fxml

         

MainController.java

 package controllers; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.layout.BorderPane; public class MainController implements Initializable { @FXML private BorderPane mainPane; @Override public void initialize(URL url, ResourceBundle resourceBundle) { initializeFontSizeManager(); } private void initializeFontSizeManager() { // Cf. https://stackoverflow.com/questions/13246211/javafx-how-to-get-stage-from-controller-during-initialization mainPane.sceneProperty().addListener((observableScene, oldScene, newScene) -> { // We need a scene to work on if (oldScene == null && newScene != null) { DoubleProperty fontSize = new SimpleDoubleProperty(0); fontSize.bind(newScene.widthProperty().add(newScene.heightProperty()) .divide(1280 + 720) // I know, it's a very rough approximation :) .multiply(100)); // get a suitable value to put before the '%' symbol in the style mainPane.styleProperty().bind( Bindings.concat("-fx-font-size: ", fontSize.asString("%.0f")).concat("%;")); } }); } }