【问题标题】:JavaFX - Access fx:id from nested FXMLJavaFX - 从嵌套的 FXML 访问 fx:id
【发布时间】:2016-11-28 01:44:41
【问题描述】:

所以,这是我的主要 FXML 文件,名为“Home.fxml”:

<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
    <fx:include source="MenuBar.fxml" />
   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" text="Welcome to MSMusic" textAlignment="CENTER">
      <font>
         <Font size="62.0" />
      </font>
   </Label>
    <fx:include source="PlayerElement.fxml" />
</VBox>

在该文件中,我包含一个音乐播放器元素,该元素的标签带有 fx:id 'songTime',当我尝试在 Home.fxml 的控制器中使用'songTime'时,我得到一个 NullPointerException,因为 fx:嵌套 fxml 中的 id 似乎不可用。有没有简单的方法来实现这一点?

【问题讨论】:

    标签: java javafx view controller fxml


    【解决方案1】:

    将 UI 控件暴露在控制器之外的 FXML 文件中通常是不好的做法。

    您可以将包含的 FXML 文件中的控制器注入到您的 Home.fxml 文件的控制器中:

    <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
        <fx:include source="MenuBar.fxml" />
       <Label alignment="CENTER" maxWidth="1.7976931348623157E308" text="Welcome to MSMusic" textAlignment="CENTER">
          <font>
             <Font size="62.0" />
          </font>
       </Label>
        <fx:include fx:id="player" source="PlayerElement.fxml" />
    </VBox>
    

    Home.fxml 的控制器中你可以这样做

    public class HomeController {
    
        @FXML
        private PlayerElementController playerController ;
    
        // ...
    }
    

    其中PlayerElementControllerPlayerElement.fxml 文件的控制器类。这在"Nested Controllers" in the documentation 下进行了描述,但本质上只是使用名称为fx:id 的字段用于fx:include 并附加"Controller",因此这里fx:id="player" 用于包含允许您注入控制器实例包含的 FXML 文件到字段playerController

    现在只需在PlayerElementController 中定义一些方法来设置所需的文本:

    public class PlayerElementController {
    
        @FXML
        private Label songTime ;
    
        // note: might want to make the parameter a more appropriate type than string,
        // and perform the conversion to a string in this method...
        public void setSongTime(String songTime) {
            this.songTime.setText(songTime);
        }
    
        // and similarly here for the return type
        public String getSongTime() {
            return songTime.getText();
        }
    
        // ...
    }
    

    现在回到你的HomeController,你需要做的就是

    playerController.setSongTime(...);
    

    设置文本。如果您需要与标签关联的其他功能,只需定义与您需要的行为相对应的适当方法即可。

    【讨论】:

    • 这对我来说似乎很神奇,应用程序如何知道它正在获取正确的控制器,因为可能有多个 PlayerElementController 实例,对吧?这样做的唯一一件事就是说给我任何 PlayerElementController,至少在我看来是这样。
    • @ScriptKiddy 它在加载与特定fx:include 对应的FXML 文件时注入由FXMLLoader 创建的实例。如果您有其他fx:includes 具有相同的文件,它们将有不同的fx:ids,因此相应的控制器将被注入到不同的字段。就像注入 UI 元素对应的字段一样,映射是通过fx:id。所以不,没有魔法,它不是任意选择一个实例。
    • 嗯好的,待会去看看,谢谢回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2012-09-14
    • 2015-04-06
    • 2017-12-02
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多