gpt4 book ai didi

内部自定义组件上未调用 JavaFXinitialize()

转载 作者:行者123 更新时间:2023-12-01 18:06:38 24 4
gpt4 key购买 nike

我正在使用 javaFX,我需要将自定义组件放入我的场景中。因此,我有“main_pane.fxml”,其网格 Pane 包含我的组件(例如 DocumentModule)。

main_pane.fxml

<GridPane  xmlns:fx="http://javafx.com/fxml" fx:controller="GUI.MainPane" gridLinesVisible="true" > 
<padding>
<Insets bottom="0" top="0" left="0" right="0" />
</padding>
.
.
.
<DocumentModule fx:id="documentModule"
minWidth="200" minHeight="400"
GridPane.columnIndex="0" GridPane.rowIndex="1">
.
.
.
</DocumentModule>
.
.
.

它们每个都在单独的 fxml 文件中定义。

文档模块.fxml

<GridPane  xmlns:fx="http://javafx.com/fxml"  fx:controller="GUI.DocumentModule" >
<padding>
<Insets bottom="0" top="0" left="0" right="0" />
</padding>
<ToolBar fx:id="toolBar" GridPane.rowIndex = "0" GridPane.columnIndex = "0" orientation="HORIZONTAL" >
.
.
.
</ToolBar>
<ScrollPane fx:id="scrollPane" hbarPolicy="AS_NEEDED" vbarPolicy="AS_NEEDED" GridPane.rowIndex = "1" GridPane.columnIndex = "0">
<DocumentView fx:id="documentView"/>
</ScrollPane>
</GridPane>

问题是 DocumentModule 在构造后未初始化。它的构造函数被调用,但没有调用它的initialize(URL location, ResourceBundle resources)方法。因此,不会注入(inject) fxml 中的对象。

文档模块的 Controller 代码

public class DocumentModule extends GridPane implements Initializable {
protected Document document;

@FXML
private DocumentView documentView;

@FXML
private ScrollPane scrollPane;
.
.
.
public DocumentModule() {
System.out.println("Document Module constructed.");
//this is called correctly

}
@Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("Document Module initialized.");
//This is not called at all.
}

}

对于 MainPane 来说一切正常,但对于任何内部组件都不起作用。组件树似乎构建正确,只是内部组件未初始化。此外,内部组件不会在应用程序场景中显示(如果我直接加载它们的 fxml,它们就会工作,如果我使用 fx:include 它们只会显示)。

主 Pane Controller

public final class MainPane extends GridPane implements Initializable {

@FXML
private DocumentModule documentModule;

@FXML
private EditModule editModule;


public MainPane() {
System.out.println("Main Pane constructed.");
}

@Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("Main Pane initialized.");
}

}

应用入口类的启动方法

@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("main_pane.fxml"));
GridPane root = fxmlLoader.load();
Scene scene = new Scene(root, 800, 600);
primaryStage.setMaximized(true);
primaryStage.setMinWidth(800);
primaryStage.setMinHeight(600);
primaryStage.setTitle("App");
primaryStage.setScene(scene);
primaryStage.show();
}

我没有找到任何有同样问题的主题/页面/博客。他们中很少有人有类似的症状,但没有任何解决方案对我有帮助。有谁知道为什么内部组件没有调用初始化?

谢谢!汤姆

最佳答案

您的代码中没有任何地方实际加载 document_module.fxml ,所以那里定义的元素永远不会被创建。 initialize()FXMLLoader 时,在 Controller 上调用 fxml 文件的方法加载该文件,但由于您从未加载 fxml 文件,initialize()方法从未被调用。

元素<DocumentModule>在您的主 FXML 中只会导致 DocumentModule要实例化的类(通过调用其无参数构造函数),但没有从那里到 fxml 文件的链接。

您似乎正在尝试遵循 FXML custom component pattern 。为此,您需要在自定义组件构造函数中加载 FXML 文件。在fxml中指定动态根并且不指定 Controller 类,并在 FXMLLoader 上设置两者在调用加载之前:

文档模块.fxml:

<fx:root type="GridPane"  xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="0" top="0" left="0" right="0" />
</padding>
<ToolBar fx:id="toolBar" GridPane.rowIndex = "0" GridPane.columnIndex = "0" orientation="HORIZONTAL" >
.
.
.
</ToolBar>
<ScrollPane fx:id="scrollPane" hbarPolicy="AS_NEEDED" vbarPolicy="AS_NEEDED" GridPane.rowIndex = "1" GridPane.columnIndex = "0">
<DocumentView fx:id="documentView"/>
</ScrollPane>
</fx:root>

DocumentModule.java:

public class DocumentModule extends GridPane implements Initializable {
protected Document document;

@FXML
private DocumentView documentView;

@FXML
private ScrollPane scrollPane;
.
.
.
public DocumentModule() {
System.out.println("Document Module constructed.");

FXMLLoader loader = new FXMLLoader(getClass().getResource("document_module.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException exc) {
exc.printStackTrace();
// this is pretty much fatal, so:
System.exit(1);
}

}
@Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("Document Module initialized.");
// This will now be called after the @FXML-annotated fields are initialized.
}

}

关于内部自定义组件上未调用 JavaFXinitialize(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35949666/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com