title: Javafx: Binding font size to container
body: <p>I am currently working on my final year project which is to create a Sudoku game/solver. The problem I have is that I am cannot find a method of resizing font size to that of its container when using a scene framework.</p>
  
  <p>I would like to have the font size of a label change to the corresponding size of the gridpane it is within. I however am finding it hard to bind the properties I need such as 'widthProperty' and 'heightProperty' to that of 'Font.font(size)'</p>
  
  <p>The difference of this question to other binding questions, is that my scene framework interferes with putting the binding for controls in the initialize method of a controller. I cannot do this as all of my controllers are initialized on start up not when they are shown to the scene</p>
  
  <p>Here is all my code:</p>
  
  <p><strong>Main.java</strong></p>
  
  <pre><code>package Controller;
  
  import javafx.application.Application;
  import javafx.scene.Scene;
  import javafx.scene.layout.StackPane;
  import javafx.stage.Stage;
  
  public class Main extends Application {
  
      public static String mainMenu = "Main Menu";
      public static String mainMenuFXML = "/FXML/MainMenu.fxml";
      public static String chooseLevel = "Level Selection";
      public static String chooseLevelFXML = "/FXML/ChooseLevel.fxml";
  
      //Global Variable to be accessed across all classes
      //To be used to determine which scenes are loaded in the HashMap and also which scene has been set
      public static SceneFramework mainController = new SceneFramework();
  
      @Override
      public void start(Stage primaryStage) throws Exception{
  
          //Only the main menu scene is needed to be loaded at the start
          mainController.loadScene(Main.mainMenu, Main.mainMenuFXML);
          mainController.setScene(Main.mainMenu);
  
          StackPane root = new StackPane();
          root.getChildren().addAll(mainController);
          Scene scene = new Scene(root);
          primaryStage.setScene(scene);
          primaryStage.show();
      }
  
      public static void main(String[] args) {
  
          launch(args);
      }
  }
  </code></pre>
  
  <p><strong>SceneFramework.java</strong></p>
  
  <pre><code>package Controller;
  
  
  import javafx.fxml.FXMLLoader;
  import javafx.scene.Node;
  import javafx.scene.Parent;
  import javafx.scene.layout.StackPane;
  
  import java.util.HashMap;
  
  public class SceneFramework extends StackPane{
  
      //Constructor for the class
      public SceneFramework(){
          //The keyword super, overrides methods from the superclass
          super();
      }
  
      //This HashMap is used to hold the screens(scenes) to be used within the application
      protected HashMap&lt;String, Node&gt; scenes = new HashMap&lt;&gt;();
  
      //Adds the selected scene to the HashMap
      public void addScene(String title, Node scene) {
          scenes.put(title, scene);
      }
  
      //Returns the Node with the specified title for use within application
      public Node getScene(String title) {
          return scenes.get(title);
      }
  
      //Removes the selected scene from the framework
      public boolean unloadScene(String title){
          if(scenes.remove(title) == null){
              System.out.println("Scene cannot be located or it doesn't exist");
              return false;
          } else{
              return true;
          }
      }
  
      public boolean loadScene(String title, String resource){
          //encase code segment in try for exception handling,
          // as resources are required to be found and then loaded into memory
          try{
              //Load FXML File
              FXMLLoader loadedFXMLFile = new FXMLLoader(getClass().getResource(resource));
  
              //Get Parent of scene
              Parent loadScene = loadedFXMLFile.load();
  
              //Get the Controller class of the parent
              SetSceneParent sceneController = (loadedFXMLFile.getController());
  
              //Method of making sure every scene knows who it's parent is
              sceneController.setSceneParent(this);
  
              //Add scene to HashMap
              addScene(title, loadScene);
              return true;
  
          }catch (Exception e){
              //If FXML resource can't be loaded then generate this
              System.out.println("Could't load FXML file");
              return false;
          }
      }
  
      //Method for showing scenes
      //If one scenes if wanting to be shown then it is added to the root
      //If multiple scenes are wanting to be loaded then the first scene is removed and the new scene is then displayed
      public boolean setScene(final String title){
          //Check to see if scene can be found
          if(scenes.get(title) != null) {
              if(!getChildren().isEmpty()){
  
                  getChildren().remove(0);
                  getChildren().add(0 ,scenes.get(title));
  
              }else{
                      getChildren().add(scenes.get(title));
              }
              return true;
          } else{
              System.out.println("Scene not located!!!");
              return false;
          }
      }
  }
  </code></pre>
  
  <p><strong>SetSceneParent.java</strong></p>
  
  <pre><code>package Controller;
  
  import Controller.SceneFramework;
  
  public interface SetSceneParent {
  
     void setSceneParent(SceneFramework sceneParent);
  }
  </code></pre>
  
  <p><strong>MainMenuController.java</strong></p>
  
  <pre><code>package Controller;
  
  import javafx.fxml.FXML;
  import javafx.fxml.Initializable;
  import javafx.scene.control.Button;
  
  import java.net.URL;
  import java.util.ResourceBundle;
  
  
  public class MainMenuController implements Initializable, SetSceneParent {
  
      @FXML
      public Button playButton, optionsButton, quitButton;
  
  
      @Override
      public void initialize(URL location, ResourceBundle resources) {
          SelectionStatus.initialize();
      }
  
      @Override
      public void setSceneParent(SceneFramework sceneParent) {
          //Sets the parent of the scene by using the global variable of the class SceneFramework
          Main.mainController = sceneParent;
      }
  
      public void handlePlayButtonAction(){
          //On clicking of the play button
          //The user is taken to the level difficulty scene
  
          Main.mainController.loadScene(Main.chooseLevel, Main.chooseLevelFXML);
          Main.mainController.setScene(Main.chooseLevel);
          Main.mainController.unloadScene(Main.mainMenu);
      }
  
  }
  </code></pre>
  
  <p><strong>MainMenu.fxml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;?import javafx.scene.text.*?&gt;
  &lt;?import java.lang.*?&gt;
  &lt;?import javafx.geometry.*?&gt;
  &lt;?import javafx.scene.control.*?&gt;
  &lt;?import javafx.scene.layout.*?&gt;
  
  &lt;BorderPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller.MainMenuController"&gt;
     &lt;center&gt;
        &lt;HBox&gt;
           &lt;children&gt;
              &lt;VBox alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" BorderPane.alignment="TOP_CENTER" HBox.hgrow="ALWAYS"&gt;
                  &lt;children&gt;
                    &lt;Label alignment="TOP_CENTER" maxHeight="120.0" prefHeight="60.0" text="Sudoku Solver" textAlignment="CENTER" underline="true" wrapText="true" VBox.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="48.0" /&gt;
                       &lt;/font&gt;
                       &lt;VBox.margin&gt;
                          &lt;Insets right="10.0" /&gt;
                       &lt;/VBox.margin&gt;
                    &lt;/Label&gt;
                      &lt;Button fx:id="playButton" maxHeight="175.0" maxWidth="1400.0" mnemonicParsing="false" onAction="#handlePlayButtonAction" prefHeight="60.0" prefWidth="300.0" text="Play" VBox.vgrow="ALWAYS"&gt;
                          &lt;VBox.margin&gt;
                              &lt;Insets /&gt;
                          &lt;/VBox.margin&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="18.0" /&gt;
                       &lt;/font&gt;
                      &lt;/Button&gt;
                    &lt;Region maxHeight="80.0" prefHeight="0.0" VBox.vgrow="ALWAYS" /&gt;
                      &lt;Button fx:id="optionsButton" maxHeight="175.0" maxWidth="1400.0" mnemonicParsing="false" prefHeight="60.0" prefWidth="300.0" text="Options" VBox.vgrow="ALWAYS"&gt;
                          &lt;VBox.margin&gt;
                              &lt;Insets /&gt;
                          &lt;/VBox.margin&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="18.0" /&gt;
                       &lt;/font&gt;
                      &lt;/Button&gt;
                    &lt;Region maxHeight="80.0" prefHeight="0.0" VBox.vgrow="ALWAYS" /&gt;
                      &lt;Button fx:id="quitButton" maxHeight="175.0" maxWidth="1400.0" mnemonicParsing="false" prefHeight="60.0" prefWidth="300.0" text="Quit" VBox.vgrow="ALWAYS"&gt;
                          &lt;VBox.margin&gt;
                              &lt;Insets /&gt;
                          &lt;/VBox.margin&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="18.0" /&gt;
                       &lt;/font&gt;
                      &lt;/Button&gt;
                  &lt;/children&gt;
              &lt;/VBox&gt;
           &lt;/children&gt;
        &lt;/HBox&gt;
     &lt;/center&gt;
     &lt;left&gt;
        &lt;HBox BorderPane.alignment="CENTER"&gt;
           &lt;children&gt;
              &lt;Region maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" /&gt;
           &lt;/children&gt;
        &lt;/HBox&gt;
     &lt;/left&gt;
     &lt;right&gt;
        &lt;HBox BorderPane.alignment="CENTER"&gt;
           &lt;children&gt;
              &lt;Region maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS" /&gt;
           &lt;/children&gt;
        &lt;/HBox&gt;
     &lt;/right&gt;
     &lt;bottom&gt;
        &lt;VBox BorderPane.alignment="CENTER"&gt;
           &lt;children&gt;
              &lt;Region prefHeight="60.0" VBox.vgrow="ALWAYS" /&gt;
           &lt;/children&gt;
        &lt;/VBox&gt;
     &lt;/bottom&gt;
  &lt;/BorderPane&gt;
  </code></pre>
  
  <p><strong>ChooseLevelController.java</strong></p>
  
  <pre><code>package Controller;
  
  import javafx.fxml.FXML;
  import javafx.fxml.Initializable;
  import javafx.scene.control.Button;
  import javafx.scene.control.Label;
  import javafx.scene.layout.GridPane;
  
  import java.net.URL;
  import java.util.ResourceBundle;
  
  public class ChooseLevelController implements Initializable, SetSceneParent {
  
      @FXML
      public Label lblLevelSelection, lblLevel1, lblLevel2, lblLevel3, lblLevel4, lblLevel5, lblLevel6, lblLevel7, lblLevel8, lblLevel9, lblLevel10; // Value injected by FXMLLoader
      public Button backButton;
      public GridPane gridPaneCenter;
  
      @Override
      public void initialize(URL location, ResourceBundle resources) {
  
          //Assert code is to be used in debugging making sure references to files and their elements are correct
          assert lblLevel1 != null : "fx:id=\"lblLevel1\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel2 != null : "fx:id=\"lblLevel2\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel3 != null : "fx:id=\"lblLevel3\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel4!= null : "fx:id=\"lblLevel4\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel5 != null : "fx:id=\"lblLevel5\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel6 != null : "fx:id=\"lblLevel6\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel7 != null : "fx:id=\"lblLevel7\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel8 != null : "fx:id=\"lblLevel8\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel9 != null : "fx:id=\"lblLevel9\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
          assert lblLevel10 != null : "fx:id=\"lblLevel10\" was not injected: check your FXML file 'ChooseLevel.fxml'.";
  
      }
  
      @Override
      public void setSceneParent(SceneFramework screenParent) {
          //Sets the parent of the scene by using the global variable of the class SceneFramework
          Main.mainController = screenParent;
      }
  
      //Logic code
      @FXML
      public void mouseClickedLevelLabel() {
  
          //Load the play screen when any Label is pressed
          lblLevel1.setOnMouseClicked(e -&gt; handleLabelClick(1));
          lblLevel2.setOnMouseClicked(e -&gt; handleLabelClick(2));
          lblLevel3.setOnMouseClicked(e -&gt; handleLabelClick(3));
          lblLevel4.setOnMouseClicked(e -&gt; handleLabelClick(4));
          lblLevel5.setOnMouseClicked(e -&gt; handleLabelClick(5));
          lblLevel6.setOnMouseClicked(e -&gt; handleLabelClick(6));
          lblLevel7.setOnMouseClicked(e -&gt; handleLabelClick(7));
          lblLevel8.setOnMouseClicked(e -&gt; handleLabelClick(8));
          lblLevel9.setOnMouseClicked(e -&gt; handleLabelClick(9));
          lblLevel10.setOnMouseClicked(e -&gt; handleLabelClick(10));
      }
  
      @FXML
      public void handleBackButtonAction() {
          //On clicking of the back button
          //The user is taken to the level difficulty scene
  
          Main.mainController.loadScene(Main.mainMenu, Main.mainMenuFXML);
          Main.mainController.setScene(Main.mainMenu);
          Main.mainController.unloadScene(Main.chooseLevel);
  
      }
  }
  </code></pre>
  
  <p><strong>ChooseLevel.fxml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;?import javafx.geometry.*?&gt;
  &lt;?import javafx.scene.text.*?&gt;
  &lt;?import javafx.scene.control.*?&gt;
  &lt;?import java.lang.*?&gt;
  &lt;?import javafx.scene.layout.*?&gt;
  
  &lt;BorderPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller.ChooseLevelController"&gt;
     &lt;center&gt;
        &lt;VBox alignment="CENTER" BorderPane.alignment="CENTER"&gt;
           &lt;children&gt;
              &lt;GridPane fx:id="gridPaneCenter" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1500.0" prefHeight="242.0" prefWidth="475.0" BorderPane.alignment="CENTER" VBox.vgrow="ALWAYS"&gt;
                &lt;columnConstraints&gt;
                  &lt;ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /&gt;
                  &lt;ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /&gt;
                    &lt;ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /&gt;
                    &lt;ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /&gt;
                    &lt;ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /&gt;
                &lt;/columnConstraints&gt;
                &lt;rowConstraints&gt;
                  &lt;RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="137.0" vgrow="ALWAYS" /&gt;
                  &lt;RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="138.0" vgrow="ALWAYS" /&gt;
                &lt;/rowConstraints&gt;
                 &lt;children&gt;
                    &lt;Label fx:id="lblLevel1" onMousePressed="#mouseClickedLevelLabel" text="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel2" onMouseClicked="#mouseClickedLevelLabel" onMousePressed="#mouseClickedLevelLabel" text="2" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel3" onMousePressed="#mouseClickedLevelLabel" text="3" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel4" onMousePressed="#mouseClickedLevelLabel" text="4" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel5" onMousePressed="#mouseClickedLevelLabel" text="5" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel6" onMouseClicked="#mouseClickedLevelLabel" onMousePressed="#mouseClickedLevelLabel" text="6" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel7" onMousePressed="#mouseClickedLevelLabel" text="7" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel8" onMousePressed="#mouseClickedLevelLabel" text="8" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel9" onMousePressed="#mouseClickedLevelLabel" text="9" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                    &lt;Label fx:id="lblLevel10" onMousePressed="#mouseClickedLevelLabel" text="10" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"&gt;
                       &lt;font&gt;
                          &lt;Font name="System Bold" size="36.0" /&gt;
                       &lt;/font&gt;
                    &lt;/Label&gt;
                 &lt;/children&gt;
              &lt;/GridPane&gt;
           &lt;/children&gt;
        &lt;/VBox&gt;
     &lt;/center&gt;
     &lt;top&gt;
        &lt;GridPane fx:id="gridPaneTop"&gt;
           &lt;columnConstraints&gt;
              &lt;ColumnConstraints hgrow="ALWAYS" maxWidth="207.0" minWidth="10.0" prefWidth="20.0" /&gt;
              &lt;ColumnConstraints hgrow="SOMETIMES" maxWidth="207.0" minWidth="10.0" prefWidth="58.0" /&gt;
              &lt;ColumnConstraints hgrow="ALWAYS" maxWidth="207.0" minWidth="10.0" prefWidth="105.0" /&gt;
              &lt;ColumnConstraints hgrow="ALWAYS" maxWidth="451.0" minWidth="10.0" prefWidth="418.0" /&gt;
           &lt;/columnConstraints&gt;
           &lt;rowConstraints&gt;
              &lt;RowConstraints minHeight="10.0" vgrow="SOMETIMES" /&gt;
           &lt;/rowConstraints&gt;
           &lt;children&gt;
              &lt;Button fx:id="backButton" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleBackButtonAction" prefHeight="30.0" prefWidth="0.0" text="Back" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" /&gt;
              &lt;Separator prefHeight="63.0" prefWidth="73.0" visible="false" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS" /&gt;
              &lt;Label fx:id="lblLevelSelection" text="Level Selection" underline="true" GridPane.columnIndex="3"&gt;
                 &lt;font&gt;
                    &lt;Font name="System Bold" size="36.0" /&gt;
                 &lt;/font&gt;
              &lt;/Label&gt;
              &lt;Separator prefHeight="63.0" prefWidth="73.0" visible="false" /&gt;
           &lt;/children&gt;
        &lt;/GridPane&gt;
     &lt;/top&gt;
     &lt;bottom&gt;
        &lt;Region prefHeight="36.0" prefWidth="600.0" BorderPane.alignment="CENTER" /&gt;
     &lt;/bottom&gt;
     &lt;left&gt;
        &lt;HBox&gt;
           &lt;children&gt;
              &lt;Region maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="50.0" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS" /&gt;
           &lt;/children&gt;
        &lt;/HBox&gt;
     &lt;/left&gt;
     &lt;right&gt;
        &lt;HBox&gt;
           &lt;children&gt;
              &lt;Region maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="50.0" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS" /&gt;
           &lt;/children&gt;
        &lt;/HBox&gt;
     &lt;/right&gt;
  &lt;/BorderPane&gt;
  </code></pre>