Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaFX中绑定字体大小?_Java_User Interface_Data Binding_Fonts_Javafx - Fatal编程技术网

在JavaFX中绑定字体大小?

在JavaFX中绑定字体大小?,java,user-interface,data-binding,fonts,javafx,Java,User Interface,Data Binding,Fonts,Javafx,我想把我的申请表弄成液体。但是,当我将窗口变大时,与UI元素相比,字体看起来很小。最终,当我调整窗口大小时,我希望文本的大小变大或变小。我知道理论上我可以用style属性实现这一点,但在某些情况下,我已经将该属性绑定到了其他东西 我知道有“fontProperty”方法,但我没有什么可以绑定它,因为我不知道如何创建具有同步大小的动态ObjectProperty。我该怎么办 编辑:为了避免混淆,我试图根据其他因素更改字体大小,而不是相反。设置.root-fx字体大小 为您的应用程序创建一个 在sy

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

我知道有“fontProperty”方法,但我没有什么可以绑定它,因为我不知道如何创建具有同步大小的动态ObjectProperty。我该怎么办


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

设置.root-fx字体大小

  • 为您的应用程序创建一个
  • 在sylesheet
    .root
    选择器中,将
    -fx font size
    设置为所需的值:

    .根{ -fx字体大小:40px; }

  • 为什么这样做

    这是因为:

  • 所有默认控件都基于单位(基于默认字体大小)
  • -fx字体大小
    是一种样式
  • 一切都是从根继承的
  • 完成此操作后,所有控件(以及其中的文本)将自动调整大小,以适合指定的字体大小

    相关样本

    相关信息

    em
    是一种通用单位,它不是JavaFX特有的,em单位也用于HTML-CSS中。如果有兴趣,你可以读一本书

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

    只需设置一个默认字体大小,就可以让您达到所需的90%,但这不一定是一个通用的解决方案,因为某些布局单位可能不使用em单位来指定。大多数情况下,这并不是一个真正的问题,但如果是在您的情况下,您也可以应用中描述的机制,该机制似乎可以工作,但有点笨拙

    使用表达式绑定怎么样

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

    prefWidth="${35*u.em}" prefHeight="${25*u.em}"
    
    它不是100%简洁,但可能还可以

    这些大小表达式在scene builder 1.1中工作,这很好


    下面是一个使用矩形存储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>
    
    
    

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

    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>
    
    package org.jewelsea.measure;
    公共类度量{
    私人双em;
    public void setEm(double em){this.em=em;}
    公共双getEm(){return em;}
    }
    . . .
    
    只需将fontsize要更改的所有内容放在容器中,并设置该样式或使用绑定(如果需要)

    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值。

    有一种最简单、正确的方法将字体大小绑定到容器大小,以使其具有响应性的字体缩放效果

    绑定(Bindings.concat(“-fx font-size:”
    是一个很好的选择,但是当你调整窗口大小时,它看起来非常慢,我认为这不是解决问题的正确方法

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

    private Label textTracking = new Label();
    private ObjectProperty<Font> fontTracking = new SimpleObjectProperty<Font>(Font.getDefault());
    
    最后,您需要将包装容器更改大小与动态字体大小绑定:

        widthProperty().addListener(new ChangeListener<Number>()
        {
            @Override
            public void changed(ObservableValue<? extends Number> observableValue, Number oldWidth, Number newWidth)
            {
                fontTracking.set(Font.font(newWidth.doubleValue() / 4));
            }
        });
    
    widthProperty().addListener(新的ChangeListener())
    {
    @凌驾
    
    public void changed(observeValue我有一个类似的问题,并通过以下方式解决:

  • 在CSS和FXML文件中,我以相对的方式定义了所有字体大小,只使用“em”而不是“%”或“px”
  • 在主窗口的控制器中,我将主窗格的style属性中的一个双精度值绑定到某个场景大小属性(例如,其对角线长度的粗略近似值)
  • 这是因为设置到主窗格的样式将作为修改器影响FXML中已定义的所有节点。已具有样式类的节点也会受到影响,因为新样式在级联样式表中作为样式的附加顶层出现

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

    示例文件:

    样式。css

    main.fxml


    我不想绑定到字体大小,我想实际更改字体本身。这不是正好相反吗?不管怎样,我都将对此进行升级,因为我将来肯定会使用它。我甚至不知道这是可能的:)。请编辑你的问题,以更详细地解释你想做什么。我添加了一个额外的句子。现在我读了它,我可以看到你是如何解释这个问题的。很抱歉。你是一个JavaFX神,JewelSea。我已经用这个答案解决了一个完全无关的问题。既然你在这个项目上帮了我这么多,我就去现在,如果我可以调整字体大小,它应该可以让每个人在启动屏幕上清楚地看到你的名字:D。谢谢你的帮助!这是我最初的想法,但是一些对象的-fx样式会动态绑定到其他各种属性。没有具体的方法来检测现在它被绑定到了,所以我不能使用它。我怀疑JavaFX的人会创建FontProperty,你可以用它做任何实质性的事情。没关系,只要把你想更改字体的所有内容放在一个容器中就行了。注意vbox子容器中的所有内容都是如何更改字体的。你可以用不同的cs来设置容器层s值
        widthProperty().addListener(new ChangeListener<Number>()
        {
            @Override
            public void changed(ObservableValue<? extends Number> observableValue, Number oldWidth, Number newWidth)
            {
                fontTracking.set(Font.font(newWidth.doubleValue() / 4));
            }
        });
    
    .label {
        -fx-font-size: 1.1em;
    }
    
    .title {
        -fx-font-size: 1.5em;
        -fx-font-weight: bold;
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.control.cell.*?>
    <?import javafx.scene.layout.*?>
    <BorderPane style="-fx-background-color: #fff;"
            xmlns="http://javafx.com/javafx/8"
            xmlns:fx="http://javafx.com/fxml/1"
            prefWidth="1280.0" prefHeight="720.0"
            fx:controller="controllers.MainController">
        <top>
            <Label text="Application title" styleClass="title"/>
        </top>
        <center>
            <Label text="Lorem ipsum"/>
        </center>
    </BorderPane>
    
    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("%;"));
                }
            });
        }
    }