2016-02-13 35 views
0

我目前正在編寫一個數獨求解器/遊戲應用程序。然而,我努力讓我的應用程序根據使用綁定的容器大小管理文本的大小。我正在使用一個場景框架來控制何時加載不同的FXML文件及其相應的控制器,然後顯示給用戶。Javafx綁定字體屬性與場景框架

目標:我想做到的是顯示在選擇水平FXML時,我想它,以便gridpane內的文本獲得大/小時的gridpane的大小變化。

問題:我遇到過的情況是,在場景中顯示不同的FXML時,找不到任何給定控件的文本綁定方法。我曾嘗試在控制器中使用初始化方法,但問題在於場景框架在應用程序啓動時加載並初始化所有FXML和控制器文件。

我的程序的運行順序如下:

  1. 主菜單
  2. 難度選擇
  3. 選擇水平
  4. 播放背景

謝謝你在前進,因爲這是我第一次發佈堆棧溢出。

這是相關的代碼,我有工作:

Main.java

public class Main extends Application { 

public static String mainMenu = "Main Menu"; 
public static String mainMenuFXML = "/FXML/MainMenu.fxml"; 
public static String levelDifficulty = "Difficulty Selection"; 
public static String levelDifficultyFXML = "/FXML/LevelDifficulty.fxml"; 
public static String chooseLevel = "Level Selection"; 
public static String chooseLevelFXML = "/FXML/ChooseLevel.fxml"; 
public static String playScreen = "PLay Screen"; 
public static String playScreenFXML = "/FXML/PlayScreen.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); 
} 
} 

SceneFramework.java

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<String, Node> scenes = new HashMap<>(); 

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

SetSceneParent.java

package Controller; 

import Controller.SceneFramework; 

public interface SetSceneParent { 

    void setSceneParent(SceneFramework sceneParent); 
} 

ChooseLevelController.java

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 -> handleLabelClick(1)); 
     lblLevel2.setOnMouseClicked(e -> handleLabelClick(2)); 
     lblLevel3.setOnMouseClicked(e -> handleLabelClick(3)); 
     lblLevel4.setOnMouseClicked(e -> handleLabelClick(4)); 
     lblLevel5.setOnMouseClicked(e -> handleLabelClick(5)); 
     lblLevel6.setOnMouseClicked(e -> handleLabelClick(6)); 
     lblLevel7.setOnMouseClicked(e -> handleLabelClick(7)); 
     lblLevel8.setOnMouseClicked(e -> handleLabelClick(8)); 
     lblLevel9.setOnMouseClicked(e -> handleLabelClick(9)); 
     lblLevel10.setOnMouseClicked(e -> 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.levelDifficulty, Main.levelDifficultyFXML); 
     Main.mainController.setScene(Main.levelDifficulty); 
     Main.mainController.unloadScene(Main.chooseLevel); 

    } 

    private void handleLabelClick(int levelSelected){ 
     SelectionStatus.setLevelStatus(levelSelected); 
     Main.mainController.loadScene(Main.playScreen, Main.playScreenFXML); 
     Main.mainController.setScene(Main.playScreen); 
     Main.mainController.unloadScene(Main.chooseLevel); 
    } 



} 

ChooseLevel.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.geometry.*?> 
<?import javafx.scene.text.*?> 
<?import javafx.scene.control.*?> 
<?import java.lang.*?> 
<?import javafx.scene.layout.*?> 

<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"> 
    <center> 
     <VBox alignment="CENTER" BorderPane.alignment="CENTER"> 
     <children> 
      <GridPane fx:id="gridPaneCenter" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1500.0" prefHeight="242.0" prefWidth="475.0" BorderPane.alignment="CENTER" VBox.vgrow="ALWAYS"> 
       <columnConstraints> 
       <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /> 
       <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /> 
        <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /> 
        <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /> 
        <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" /> 
       </columnConstraints> 
       <rowConstraints> 
       <RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="137.0" vgrow="ALWAYS" /> 
       <RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="138.0" vgrow="ALWAYS" /> 
       </rowConstraints> 
       <children> 
        <Label fx:id="lblLevel1" onMousePressed="#mouseClickedLevelLabel" text="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel2" onMouseClicked="#mouseClickedLevelLabel" onMousePressed="#mouseClickedLevelLabel" text="2" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel3" onMousePressed="#mouseClickedLevelLabel" text="3" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel4" onMousePressed="#mouseClickedLevelLabel" text="4" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel5" onMousePressed="#mouseClickedLevelLabel" text="5" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel6" onMouseClicked="#mouseClickedLevelLabel" onMousePressed="#mouseClickedLevelLabel" text="6" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel7" onMousePressed="#mouseClickedLevelLabel" text="7" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel8" onMousePressed="#mouseClickedLevelLabel" text="8" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel9" onMousePressed="#mouseClickedLevelLabel" text="9" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
        <Label fx:id="lblLevel10" onMousePressed="#mouseClickedLevelLabel" text="10" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> 
        <font> 
         <Font name="System Bold" size="36.0" /> 
        </font> 
        </Label> 
       </children> 
      </GridPane> 
     </children> 
     </VBox> 
    </center> 
    <top> 
     <GridPane fx:id="gridPaneTop"> 
     <columnConstraints> 
      <ColumnConstraints hgrow="ALWAYS" maxWidth="207.0" minWidth="10.0" prefWidth="20.0" /> 
      <ColumnConstraints hgrow="SOMETIMES" maxWidth="207.0" minWidth="10.0" prefWidth="58.0" /> 
      <ColumnConstraints hgrow="ALWAYS" maxWidth="207.0" minWidth="10.0" prefWidth="105.0" /> 
      <ColumnConstraints hgrow="ALWAYS" maxWidth="451.0" minWidth="10.0" prefWidth="418.0" /> 
     </columnConstraints> 
     <rowConstraints> 
      <RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> 
     </rowConstraints> 
     <children> 
      <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" /> 
      <Separator prefHeight="63.0" prefWidth="73.0" visible="false" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS" /> 
      <Label fx:id="lblLevelSelection" text="Level Selection" underline="true" GridPane.columnIndex="3"> 
       <font> 
        <Font name="System Bold" size="36.0" /> 
       </font> 
      </Label> 
      <Separator prefHeight="63.0" prefWidth="73.0" visible="false" /> 
     </children> 
     </GridPane> 
    </top> 
    <bottom> 
     <Region prefHeight="36.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> 
    </bottom> 
    <left> 
     <HBox> 
     <children> 
      <Region maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="50.0" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS" /> 
     </children> 
     </HBox> 
    </left> 
    <right> 
     <HBox> 
     <children> 
      <Region maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="50.0" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS" /> 
     </children> 
     </HBox> 
    </right> 
</BorderPane> 

回答

0

試圖運行你的代碼,但沒有成功。我得到的只是一個白色屏幕(在改變了一些東西以使其運行並加載正確的fxml之後)。 我放棄了。


所以這是我的猜測,你要完成的任務:

當你調整你的屏幕中選擇想要的字體大小與它規模。


  • 添加監聽到width屬性
  • 在您使用改變了寬度和高度的窗口/面板/對象/ w.e的處理程序。計算你的新字體大小
  • 設置新的字體大小

編輯:如果您發佈一噸的代碼,不編譯和獨立運行(如:小例子, ),請至少指向代碼的一部分,這是行不通的 - 讓人們更容易幫助你。至於你的問題是,現在它將需要相當長的時間讓人們找到一個錯誤 - 這是大部分(如果不是全部)也不會做;)


EDIT2:您還可以使用.setScaleX(double).setScaleY(double)放在您想要放大的標籤/對象上 - 您不一定需要更改字體大小。 (根據使用情況)