如何从 JavaFX2 的父控制器获取控制器的特定实例?
How to get specific instance of controller from parent controller at JavaFX2?
我有 2 个 fxml 布局,其中一个包含另一个。我尝试从父控制器 i 更新内部元素的内容。 e.当按下父控制器上的按钮时,在 imageview 上更改图像。
我使用的方法,建议here。问题是当我调用假设在 imageView (questionController.setPdfPageImage(++currentPage);
) 中更改图像的方法时,没有任何反应。我尝试了一些调试,我相信这是因为有两个完全不同的控制器实例:一个从运行时调用,另一个默认从 fxml 调用。请指出正确的解决方案。
部分main.fxml
<BorderPane
fx:id="mainContainer"
xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.package.name.MainController">
<center>
<Pane fx:id="center">
<fx:include source="question.fxml"/>
</Pane>
</center>
<bottom>
<VBox fx:id="bottom"
BorderPane.alignment="CENTER">
<children>
<Button fx:id="next" text="Next"/>
</children>
</VBox>
</bottom>
</BorderPane>
question.fxml
的一部分
<SplitPane fx:id="content"
dividerPositions="0.5"
xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.package.name.QuestionController">
<items>
<AnchorPane fx:id="questionContainer">
<children>
<ImageView fx:id="questionView" pickOnBounds="true" preserveRatio="true"/>
</children>
</AnchorPane>
</items>
</SplitPane>
部分QuestionController.java
public void setPdfPageImage(int pageNum) {
// InputStream is = QuestionController.class.getResourceAsStream(currentPdf);
InputStream is = this.getClass().getResourceAsStream(currentPdf);
Image convertedImage;
try {
PDDocument document = PDDocument.load(is);
List<PDPage> list = document.getDocumentCatalog().getAllPages();
PDPage page = list.get(pageNum);
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 128);
convertedImage = SwingFXUtils.toFXImage(image, null);
document.close();
questionView.setImage(convertedImage);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
MainController.java
的一部分
public class MainController implements Initializable {
QuestionController questionController;
@FXML // fx:id="next"
private Button next; // Value injected by FXMLLoader
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/question.fxml"));
try {
loader.load();
} catch (IOException e1) {
e1.printStackTrace();
}
questionController = (QuestionController) loader.getController();
next.setOnAction(event -> {
//TODO remove hardcoded value 49
if (currentPage < 49)
questionController.setPdfPageImage(++currentPage);
else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Quiz finished");
alert.setHeaderText(null);
alert.setContentText("This was the last question. Thank you!");
alert.showAndWait();
}
});
}
}
要注入包含的 fxml 的控制器,请将 fx:id
属性添加到 fx:include
标记:
<fx:include fx:id="question" source="question.fxml"/>
这会将控制器注入名称为 <fx:id>Controller
的字段,即在本例中为 questionController
(如果这样的字段对加载程序可见)。
(同时从 initialize
方法中删除加载器部分)。
我有 2 个 fxml 布局,其中一个包含另一个。我尝试从父控制器 i 更新内部元素的内容。 e.当按下父控制器上的按钮时,在 imageview 上更改图像。
我使用的方法,建议here。问题是当我调用假设在 imageView (questionController.setPdfPageImage(++currentPage);
) 中更改图像的方法时,没有任何反应。我尝试了一些调试,我相信这是因为有两个完全不同的控制器实例:一个从运行时调用,另一个默认从 fxml 调用。请指出正确的解决方案。
部分main.fxml
<BorderPane
fx:id="mainContainer"
xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.package.name.MainController">
<center>
<Pane fx:id="center">
<fx:include source="question.fxml"/>
</Pane>
</center>
<bottom>
<VBox fx:id="bottom"
BorderPane.alignment="CENTER">
<children>
<Button fx:id="next" text="Next"/>
</children>
</VBox>
</bottom>
</BorderPane>
question.fxml
的一部分<SplitPane fx:id="content"
dividerPositions="0.5"
xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.package.name.QuestionController">
<items>
<AnchorPane fx:id="questionContainer">
<children>
<ImageView fx:id="questionView" pickOnBounds="true" preserveRatio="true"/>
</children>
</AnchorPane>
</items>
</SplitPane>
部分QuestionController.java
public void setPdfPageImage(int pageNum) {
// InputStream is = QuestionController.class.getResourceAsStream(currentPdf);
InputStream is = this.getClass().getResourceAsStream(currentPdf);
Image convertedImage;
try {
PDDocument document = PDDocument.load(is);
List<PDPage> list = document.getDocumentCatalog().getAllPages();
PDPage page = list.get(pageNum);
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 128);
convertedImage = SwingFXUtils.toFXImage(image, null);
document.close();
questionView.setImage(convertedImage);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
MainController.java
的一部分 public class MainController implements Initializable {
QuestionController questionController;
@FXML // fx:id="next"
private Button next; // Value injected by FXMLLoader
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/question.fxml"));
try {
loader.load();
} catch (IOException e1) {
e1.printStackTrace();
}
questionController = (QuestionController) loader.getController();
next.setOnAction(event -> {
//TODO remove hardcoded value 49
if (currentPage < 49)
questionController.setPdfPageImage(++currentPage);
else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Quiz finished");
alert.setHeaderText(null);
alert.setContentText("This was the last question. Thank you!");
alert.showAndWait();
}
});
}
}
要注入包含的 fxml 的控制器,请将 fx:id
属性添加到 fx:include
标记:
<fx:include fx:id="question" source="question.fxml"/>
这会将控制器注入名称为 <fx:id>Controller
的字段,即在本例中为 questionController
(如果这样的字段对加载程序可见)。
(同时从 initialize
方法中删除加载器部分)。