Java 打开FXMLLoader';s控制器
我正在创建JavaFX应用程序。是否有可能在JavaFX应用程序中打开控制器窗口。例如,我有应用程序的主屏幕,但当我打开其他modalWindow输入数据时,最后我输入了所有数据并单击保存按钮。ModalWindow应为不着色,主屏幕应刷新。我想打电话给家长控制器,从孩子控制器打电话。但是我在做这件事的时候出错了。任何其他的建议都是有用的Java 打开FXMLLoader';s控制器,java,intellij-idea,javafx,fxml,fxmlloader,Java,Intellij Idea,Javafx,Fxml,Fxmlloader,我正在创建JavaFX应用程序。是否有可能在JavaFX应用程序中打开控制器窗口。例如,我有应用程序的主屏幕,但当我打开其他modalWindow输入数据时,最后我输入了所有数据并单击保存按钮。ModalWindow应为不着色,主屏幕应刷新。我想打电话给家长控制器,从孩子控制器打电话。但是我在做这件事的时候出错了。任何其他的建议都是有用的 Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2428)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
at controllers.ExitDialogController.setLocaleToSave(ExitDialogController.java:92)
at controllers.AddDialogDepatureController.lambda$onClick$4(AddDialogDepatureController.java:221)
at controllers.AddDialogDepatureController$$Lambda$359/1446130991.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8216)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
我的孩子控制器类
if(new HttpRequests().departPost(jsonObject))
{
info.setStyle("-fx-text-fill: green");
info.setText(myResourceBundle.getString("infoSave"));
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource(FxmlViews.MainScreen.mainSc));
try
{
AnchorPane frame = fxmlLoader.load();
MainScreenController mainScreenController = (MainScreenController)fxmlLoader.getController();
mainScreenController.updateTable(myResourceBundle);
} catch (IOException e)
{
e.printStackTrace();
}
success = true;
}
当我查看Stacktrace时,我发现它并不抱怨创建控制器 它首先抱怨无法加载FXML文件。不知怎的,它找不到它。因此,它会中止—甚至在到达要加载控制器的行之前(该行看起来很好): 线程“JavaFX应用程序线程”中出现异常 java.lang.IllegalStateException:未设置位置。 在javafx.fxml.fxmloader.loadImpl(fxmloader.java:2428) 在javafx.fxml.fxmloader.load(fxmloader.java:2403) 您可能需要仔细查看“FxmlViews.MainScreen.mainSc”的值。它很可能指向错误的方向 加载控制器两次的示例:
String filename = "yourfxm.fxml";
FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
var node = loader.load();
var controller = loader.getController();
loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
node = loader.load();
controller = loader.getController();
JavaFXAPI只允许通过FXMLLoader.load()方法获取控件上的引用。对于FXMLLoader实例,您可以执行以下操作(就像您已经执行的一样:-): 这意味着:
希望这有助于 这里有一个从FXML文件替换自身的控制器。 它很简单,只有一个按钮可以触发重播,但确实如此。 舞台、场景和控制器作为静态变量存储,将所有内容保存在一个文件中。你当然可以把它们存放在任何你想要的地方
public class RootReplacingItselfController implements Initializable {
public static RootReplacingItselfController controller = null;
public static Stage stage = null;
public static Scene scene = null;
public final static String filename = "/fxml/RootReplacingItself.fxml";
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void replaceme(ActionEvent event) {
try {
//open an additional modal Dialog
FXMLLoader dialogloader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Stage dialog = new Stage();
dialog.setScene(new Scene(dialogloader.load()));
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(stage);
dialog.showAndWait();
//When the dialog is done replace myself:
FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Parent node = loader.load();
controller= loader.getController();
scene.setRoot(node);
} catch (IOException ex) {}
}
public static RootReplacingItselfController create(){
try {
FXMLLoader loader = new FXMLLoader(FXMLLoader.class.getResource(filename));
Parent node = loader.load();
controller= loader.getController();
scene = new Scene(node);
stage = new Stage();
stage.setScene(scene);
stage.show();
return controller;
} catch (IOException ex) {}
return controller;
}
}
和一个FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="151.0" prefWidth="232.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="fxControls.RootReplacingItselfController">
<children>
<Button layoutX="76.0" layoutY="76.0" mnemonicParsing="false" onAction="#replaceme" text="replaceme" />
</children>
</AnchorPane>
我对它进行了编辑,这样按钮就额外打开了一个模式子对话框。现在,该对话框再次从相同的fxml创建。
从该模式对话框中,您可以再次按下replaceme按钮并打开另一个模式对话框,然后再次从第三个模式对话框打开,依此类推
无论何时关闭模式对话框(对话框完成),都会替换根控制器。对于创建的所有子级
现在你也有了模态对话框。对话框关闭后,根目录将被替换(它始终是根目录)。当然,您也可以在对话框中使用不同的FXM
FWIW:就我个人而言,目前我无法想象一个真正的项目中我会选择这样一种方法,因为当涉及到与应用程序其他部分的交互时,它很可能会引起头痛。但这不是由我来决定的 尝试更改fxmlLoader.setLocation的参数时会发生什么。。。到getResource(/FXMLViews/MainScreen/mainSc.fxml):谢谢您的回答。是的,你在这里是完全正确的。它无法加载已经打开的FXml。我可以在这里做什么来正确地加载它并重新打开它,或者你会给我什么建议?我编辑了上面的答案,并添加了一些加载良好的代码。多次打开一个fxml文件应该不会有任何问题!另外,您的代码会抱怨找不到fxml文件。它说,文件的位置是错误的。它看错了地方。如果你能告诉我是什么让你相信的,错误的原因是文件已经打开或者控制器已经完全准备好加载,也许我能更好地理解?(我从你的帖子上看不出来)谢谢你的回复。但是它仍然会给出以前的错误。无法再次加载父Fxml,因为它已经打开。请不要发布多个答案,而是编辑一个并添加第二个答案的内容。猜你是正确的。原因是,op有两个问题:“我可以在这里做什么来正确地加载它关闭并重新打开”,另一个是stacktrace显示的错误。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="151.0" prefWidth="232.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="fxControls.RootReplacingItselfController">
<children>
<Button layoutX="76.0" layoutY="76.0" mnemonicParsing="false" onAction="#replaceme" text="replaceme" />
</children>
</AnchorPane>