Javafx 在同一场景中加载新的fxml
我有2个fxml文件:Javafx 在同一场景中加载新的fxml,javafx,fxml,scene,Javafx,Fxml,Scene,我有2个fxml文件: 布局(标题、菜单栏和内容) Anchorpane(应该放在另一个fxml文件的内容中) 我想知道如何在“主”场景的内容空间中加载第二个文件。在javaFX中工作是一件好事,还是加载一个新场景更好 我正试图做类似的事情,但不起作用: @FXML private AnchorPane content; @FXML private void handleButtonAction(ActionEvent event) { content = (Anc
- 布局(标题、菜单栏和内容)
- Anchorpane(应该放在另一个fxml文件的内容中)
@FXML
private AnchorPane content;
@FXML
private void handleButtonAction(ActionEvent event) {
content = (AnchorPane) FXMLLoader.load("vista2.fxml");
}
谢谢您的帮助。其他人可能有更好的解决方案,但我的解决方案是在外部fxml中使用一个简单的容器,如VBox,然后加载新内容并将其作为容器的子容器添加。如果您只加载一个或两个表单,这可能是一种方法。然而,对于一个更完整的框架,我发现这篇博文很有帮助:她为她的框架提供了源代码,其中包括奇特的转换。虽然它旨在管理顶级场景,但我发现它也很容易适应管理内部内容区域。为什么您的代码不起作用 加载程序将创建一个新的锚平面,但您永远不会将新窗格添加到场景图中的父窗格中 快速修复 而不是:
content = (AnchorPane) FXMLLoader.load("vista2.fxml");
写:
content.getChildren().setAll(FXMLLoader.load("vista2.fxml"));
用新vista替换内容子项。内容本身保留在场景图中,因此在设置其子对象时,同时也将它们附加到场景图中
您可能需要使用布局(例如,使用自动调整大小的布局,如堆叠窗格,而不是固定窗格),以获得您想要的确切行为
与其只是采用快速修复方法,我建议您查看下面链接的简单框架,因为这可能会为您提供一个更通用的机制,以获得您想要的行为
参考FXML导航框架
我创建了一个用于在主场景的一部分中交换fxml控制的内容窗格
该框架的机制与kithril的回答中建议的相同
动画过渡和其他:我不确定这有多有效,但似乎很好,而且比上面的方法简单得多 据我所知,这里发生的事情是这样的(它与应用程序类的Start()方法中发生的事情非常相似): 然而,我不是一个java专家,而且对编程非常陌生,所以如果有经验的人能够对它进行评估,那将是一件好事 编辑: 我找到了更简单的方法 转到MainApplication类并使静态阶段成为parentWindow
public static Stage parentWindow;
@Override
public void start(Stage stage) throws Exception {
parentWindow = stage;
Parent root = FXMLLoader.load(getClass().getResource("/ScenePackage/FXMLMainScene.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
现在,您可以进入主舞台,以便在程序中的任何位置执行类似操作来更改场景:
Parent window1;
window1 = FXMLLoader.load(getClass().getResource("/ScenePackage/FXMLWindow1.fxml"));
//Scene newSceneWindow1 = new Scene(window1);
Stage mainStage;
//mainStage = (Stage) ((Node)event.getSource()).getScene().getWindow();
mainStage = MainApplication.parentWindow;
mainStage.getScene().setRoot(newSceneWindow1); //we dont need to change whole sceene, only set new root.
我的例子是
使用:
Main.getNavigation().load(View2.URL_FXML).Show();
Main.getNavigation().GoBack();
在这种情况下,我建议您改用。首先为内容创建自定义组件:
class Content2 extends AnchorPane {
Content() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("vista2.fxml");
loader.setRoot(this);
loader.setController(this);
loader.load();
}
}
将vista2.fxml
文件根目录中的AnchorPane
标记替换为fx:root
:
<fx:root type="javafx.scene.layout.AnchorPane" xmlns:fx="http://javafx.com/fxml">
...
</fx:root>
最后,在java代码或fxml中绑定自定义事件处理程序:
@FXML
onNextButtonClick() {
Content2 content2 = new Content2();
content2.setOnPreviousButtonClick((event) -> {
Content1 content1 = new Content1();
layout.getChildren().clear();
layout.getChildren().add(content1);
});
layout.getChildren().clear();
layout.getChildren().add(content2);
}
如果您不想动态添加内容,只需将setVisible()
添加到true
或false
就可以了
我尝试了大多数答案,但这不是我想要的,所以我只是用给出的理想来做这件事:
public class Main extends Application {
public static Stage homeStage;
@Override
public void start(Stage primaryStage) throws Exception{
homeStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("mainView.fxml"));
root.getStylesheets().add(getClass().getResource("stylesheet/custom.css").toExternalForm());
homeStage.setTitle("Classification of Living Organisms");
homeStage.setScene(new Scene(root, 600, 500));
homeStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这是我的主课。带有登录窗口/page mainView.fxml的Main.java。
在mainController.java类中使用了一点@Tomasz的想法,尽管在使用之前我有点困惑:
public void gotoSubMenu(Event event) {
Parent window1;
try {
window1 = FXMLLoader.load(getClass().getResource("src/displayView.fxml"));
Stage window1Stage;
Scene window1Scene = new Scene(window1, 600, 500);
window1Stage = Main.homeStage;
window1Stage.setScene(window1Scene);
} catch (IOException e) {
e.printStackTrace();
}
}
创建了一个名为“window1”的新父窗口,该窗口在src目录中加载了名为“displayView.fxml”的第二个fxml文件。
创建主视图阶段的对象,并将场景设置为根为window1的新创建场景。
希望这对现在进入#JavaFX的人有所帮助。如果你想让按钮调用新的fxml文件,这对我来说很有用
@FXML
private void mainBClicked(ActionEvent event) throws IOException {
Stage stage;
Parent root;
stage=(Stage) ((Button)(event.getSource())).getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("MainMenu.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
保持相同的场景容器,但更改场景容器内的视图 假设要将新视图和控制器传递到的场景容器是名为sceneContainer的网格窗格布局 建立新视图的FXMLLoader对象
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Notifications.fxml"));
创建一个匹配的容器
@FXML
private void mainBClicked(ActionEvent event) throws IOException {
Stage stage;
Parent root;
stage=(Stage) ((Button)(event.getSource())).getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("MainMenu.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Notifications.fxml"));
GridPane yourNewView = fxmlLoader.load();
sceneContainer.getChildren().setAll(yourNewView);
Notifications notifications = fxmlLoader.getController();
notifications.passUserName(userName);
@FXML
public void setNotificationsViewToScene() {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Notifications.fxml"));
GridPane yourNewView = fxmlLoader.load();
sceneContainer.getChildren().setAll(yourNewView);
Notifications notifications = fxmlLoader.getController();
notifications.passUserName(userName);
} catch (IOException e) {
e.printStackTrace();
}
}