JavaFX - 从嵌套的 FXML 访问 fx:id
JavaFX - Access fx:id from nested 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 source="PlayerElement.fxml" />
</VBox>
在该文件中,当我尝试在 [=21= 的控制器中使用 'songTime' 时,我包含了一个带有 fx:id 'songTime' 标签的音乐播放器元素] 我收到 NullPointerException,因为嵌套 fxml 中的 fx:id 似乎不可用。有没有简单的方法可以做到这一点?
通常不好的做法是将 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 ;
// ...
}
其中 PlayerElementController
是 PlayerElement.fxml
文件的控制器 class。这在 "Nested Controllers" in the documentation 下进行了描述,但实际上只是使用名称为 fx:id
的字段作为 fx:include
并附加了 "Controller"
,所以这里 fx:id="player"
include 允许您将包含的 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(...);
设置文字。如果您需要与标签关联的其他功能,只需定义与您需要的行为对应的适当方法即可。
所以,这是我的主要 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>
在该文件中,当我尝试在 [=21= 的控制器中使用 'songTime' 时,我包含了一个带有 fx:id 'songTime' 标签的音乐播放器元素] 我收到 NullPointerException,因为嵌套 fxml 中的 fx:id 似乎不可用。有没有简单的方法可以做到这一点?
通常不好的做法是将 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 ;
// ...
}
其中 PlayerElementController
是 PlayerElement.fxml
文件的控制器 class。这在 "Nested Controllers" in the documentation 下进行了描述,但实际上只是使用名称为 fx:id
的字段作为 fx:include
并附加了 "Controller"
,所以这里 fx:id="player"
include 允许您将包含的 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(...);
设置文字。如果您需要与标签关联的其他功能,只需定义与您需要的行为对应的适当方法即可。