Bind Font Size in JavaFX?

前端 未结 4 458
无人及你
无人及你 2020-11-27 06:54

I\'d like to make my application fluid. However, the fonts look small compared to the UI elements when I make the windows bigger. Ultimately, I want the size of my text to g

4条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-27 07:18

    I had a similar problem and solved it this way:

    1. in the CSS and FXML files, I defined all font sizes in a relative way, using only "em" instead of "%" or "px"
    2. in the controller of the main window, I bound a double value within a style property of the main pane to some scene size property (e.g. a rough approximation of its diagonal length)

    It works because the style that is set to the main pane will affect as a modifier all the nodes that are already defined in the FXML. The nodes that already have a style class are also impacted as the new style comes as an additional top layer of styling in the cascading style sheets.

    The main advantage of this solution is to handle in a single place the font size zoom factor. Thus you don't have to find every node that has a Font property to make it working.

    Sample files:

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

提交回复
热议问题