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.