Enlazar tamaño de fuente en JavaFX?

Me gustaría hacer que mi aplicación sea fluida. Sin embargo, las fonts parecen pequeñas en comparación con los elementos de la interfaz de usuario cuando hago las ventanas más grandes. En última instancia, quiero que el tamaño del texto aumente o disminuya cuando cambie el tamaño de la ventana. Sé que podría hacerlo teóricamente con la propiedad de estilo, pero ya tengo esa propiedad ligada a otra cosa en algunos casos.

Sé que existe el método “fontProperty”, pero no tengo nada para vincularlo, ya que no puedo encontrar la manera de crear una ObjectProperty dinámica con un tamaño sincronizado. ¿Que debería hacer?

EDITAR: para evitar confusiones, estoy tratando de hacer que el tamaño de la fuente cambie en función de otros factores, y no al revés.

Simplemente coloque todo en el lugar que desea que cambie el tamaño de la fuente en un contenedor y configure ese estilo o use enlaces si lo desea.

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

No estoy seguro de a qué está vinculado su estilo, pero puede establecer varios valores CSS en la cadena de estilo.

Establecer el .root -fx-font-size

  1. Crea una hoja de estilos personalizada para tu aplicación.
  2. En el selector Sylesheet .root , establezca -fx-font-size en su valor deseado:

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

Por qué esto funciona

Esto funciona porque:

  1. Todos los controles predeterminados se basan en unidades em (que se basan en el tamaño de fuente predeterminado).
  2. -fx-font-size es un estilo heredado .
  3. Todo hereda de la raíz.

Una vez que hagas esto, todos los controles (y el texto dentro de ellos) cambiarán su tamaño automáticamente para adaptarse al tamaño de letra que hayas especificado.

Muestra relacionada

  • javafx cambio de tamaño automático y relleno de botón

Información relacionada

em es una unidad genérica que no es específica de JavaFX y las unidades em también se usan en HTML CSS. Si está interesado, puede leer un debate más amplio sobre las unidades em en comparación con otras unidades .

Usar unidades em en FXML a través del enlace de expresión

El solo hecho de establecer un tamaño de fuente predeterminado le permite llegar al 90% del camino hasta donde necesita estar, pero no es necesariamente una solución universal, ya que algunas unidades de diseño pueden especificarse sin usar unidades em. La mayoría de las veces esto no es realmente un problema, pero si es en su caso, también podría aplicar un mecanismo descrito en una publicación de la lista de correo del desarrollador de Oracle , que parece funcionar, aunque es un poco torpe.

¿Qué hay de usar un enlace de expresión?

Para 35em x 25em puedes escribir:

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

No es 100% conciso, pero quizás aceptable.

Este tipo de expresiones de tamaño funcionan en el generador de escenas 1.1, lo cual es bueno.


Aquí hay un ejemplo que usa un Rectángulo para almacenar los modificadores de ancho y alto para el archivo fxml.

                 

O bien, puede crear su propia clase de unidad y usarla en sus expresiones de tamaño, por ejemplo:

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

Existe un método más simple y adecuado para vincular el tamaño de fuente con el tamaño del contenedor, para que tenga un efecto de escala de fuente receptivo.

El bind(Bindings.concat("-fx-font-size: " es una buena alternativa, pero cuando cambias el tamaño de las ventanas parece ser muy lento y creo que no es la forma correcta de resolver el problema).

Puede declarar FontProperty y vincular esta FontProperty al Componente (Etiqueta, Texto, etc.) y finalmente crear un evento para vincular el tamaño con el tamaño de FontProperty de acuerdo con nuestro diseño:

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

Luego, en el constructor o en algún método init, puede enlazar la propiedad de la fuente de nuestro objeto con nuestra fuente dinámica:

 textTracking.fontProperty().bind(fontTracking); 

Finalmente, debe vincular el tamaño de cambio del contenedor contenedor con el tamaño de fuente dynamic:

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

Con esta solución, el ajuste dynamic de la fuente es muy fluido y rápido, incluso más que el bind(Bindings.concat("-fx-font-size: " método bind(Bindings.concat("-fx-font-size: " .

Tuve un problema similar y lo resolvió de esta manera:

  1. en los archivos CSS y FXML, definí todos los tamaños de fuente de una manera relativa, usando solo “em” en lugar de “%” o “px”
  2. en el controlador de la ventana principal, ligé un valor doble dentro de una propiedad de estilo del panel principal a alguna propiedad de tamaño de escena (por ejemplo, una aproximación aproximada de su longitud diagonal)

Funciona porque el estilo que se establece en el panel principal afectará como modificador a todos los nodos que ya están definidos en el FXML. Los nodos que ya tienen una clase de estilo también se ven afectados ya que el nuevo estilo viene como una capa superior adicional de estilo en las hojas de estilos en cascada.

La principal ventaja de esta solución es manejar en un solo lugar el factor de zoom de tamaño de fuente. Por lo tanto, no es necesario que encuentre todos los nodos que tengan una propiedad Font para que funcione.

Archivos de muestra:

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("%;")); } }); } } 
Intereting Posts