首页 > 解决方案 > 如何在 javafx 中使用 fxml 创建自定义弹出窗口?

问题描述

图形用户界面示例

要创建新版本,系统会提示用户单击 GUI 左下角的加号按钮,当他们单击此按钮时,我希望在 GUI 中心顶部覆盖一个窗格,允许用户输入设置并指定选项对于新版本,我试过这个:

 private void addRelease(Event event) throws IOException {
     Popup popup = new Popup();
    NewReleasePopupController controller = new NewReleasePopupController();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("Resources/NewReleasePopup.fxml"));
    loader.setController(controller);
    loader.load();
    popup.getContent().add((Parent)loader.load());
}

但是它似乎在加载时抛出错误,如果可能的话,我想避免加载单独的阶段,并且希望将弹出窗口的控制器嵌套在主阶段的控制器中。如果有人可以帮助我使其正常工作或有更好的方法来实现此帮助,我将尝试使用弹出类,我将不胜感激!

错误:

Caused by: javafx.fxml.LoadException: Controller value already specified.

/D:/DropDayAIO/out/production/DropDayAIO/DropDayAIO/Resources/newReleasePopup.fxml:6

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:922)
at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:980)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:227)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:752)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at DropDayAIO.HomeSceneController.addRelease(HomeSceneController.java:151)
at DropDayAIO.HomeSceneController.addNewRelease(HomeSceneController.java:128)
... 57 more

标签: javajavafx

解决方案


根据您提到的错误,我认为您已经在 FXML 文件中有一个控制器声明。像属性..fx:controller

通常在 fxml 中有这个属性声明时,如果你尝试再次设置控制器,它会抛出Caused by: javafx.fxml.LoadException: Controller value already specified

而且我相信应该是这种情况,因为您可以注意到在processAttribute方法中引发了错误。

javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:980)

您可以从 fxml 中删除它,也可以不需要在代码中设置(通过 setController())。如果你说,你想要控制器的引用,你总是可以通过loader.getController().

最重要的是,如果你设法解决Controller value already specified错误,我想接下来你会遇到Caused by: javafx.fxml.LoadException: Root value already specified.因为你试图调用 FXMLLoader 的 load() 方法两次。将节点分配给一个变量并使用该变量在弹出窗口中进行设置。

我相信下面的代码应该可以解决这个问题。试一下!!

private void addRelease(Event event) throws IOException {
     Popup popup = new Popup();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("Resources/newReleasePopup.fxml"));
    Parent parent = (Parent)loader.load(); // I am not sure you need a cast here
    newReleasePopupController controller = loader.getController();
    popup.getContent().add(parent);
}

建议:请使用正确的类命名约定。


推荐阅读