简体   繁体   中英

JavaFX - Access fx:id from nested FXML

So, this is my main FXML file, called '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>

within that file i am including a music player element which has a label with the fx:id 'songTime', when i try to use 'songTime' within the Controller of Home.fxml i get a NullPointerException, because the fx:id from within a nested fxml doesn't seem to be useable. Is there a easy way to achieve this?

It is generally bad practice to expose UI controls outside of the controller for the FXML file in which they occur.

You can inject the controller from the included FXML file into the controller for your Home.fxml file:

<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>

and in the controller for Home.fxml you can do

public class HomeController {

    @FXML
    private PlayerElementController playerController ;

    // ...
}

where PlayerElementController is the controller class for the PlayerElement.fxml file. This is described under "Nested Controllers" in the documentation , but essentially just use a field whose name is the fx:id for the fx:include with "Controller" appended to it, so here fx:id="player" for the include allows you to inject the controller instance for the included FXML file to the field playerController .

Now just define some methods in PlayerElementController for setting the desired text:

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

    // ...
}

Now back in your HomeController all you need do is

playerController.setSongTime(...);

to set the text. If you need other functionality associated with the label, just define the appropriate methods corresponding to the behavior you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM