【问题标题】:Run a second stage as dialog作为对话框运行第二阶段
【发布时间】:2013-06-20 07:29:46
【问题描述】:

我的项目有一个带有一些按钮的主 GUI(阶段):通过右键单击一个按钮,我想在另一个包中运行另一个阶段。

这是项目树

newprojectx 是带有主 GUI 和

的包
togglebuttonDraw.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent mouseEvent) {
        if (mouseEvent.isSecondaryButtonDown()){



        }
      }
    });

是鼠标右键的方法:我想从这个按钮运行fibonaccipriceretracement包中的.fxml。

togglebuttonDraw 在 NewProjectXController 类中。

非常感谢任何帮助。

编辑:这是我想通过右键运行的.fxml

【问题讨论】:

    标签: javafx-2 scenebuilder


    【解决方案1】:
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("/fibonaccipriceretracement/FibonacciPriceRetracementDialog.fxml"));
    Parent content = (Parent) loader.load();
    Stage stage = new Stage();
    stage.setScene(new Scene(content));
    stage.show();
    

    【讨论】:

    • 嗨塞巴斯蒂安,谢谢:我得到这个异常 java.lang.IllegalStateException: Location is not set。在 javafx.fxml.FXMLLoader.load(FXMLLoader.java:2021) 在 newprojectx.NewProjectXController$1.handle(NewProjectXController.java:363) 在 newprojectx.NewProjectXController$1.handle(NewProjectXController.java:355) 在 com.sun.javafx。 event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
    • 为什么要创建一个窗格?我不应该用 Scene 创建一个 Stage,然后调用 Stage.show() 吗?
    • 嘿 alberto,我在示例中犯了拼写错误,因为我必须实际输入它。它现在应该可以工作了。我做了一个窗格,因为我不知道你的 fxml 是什么样子的。如果您想要一个包含 fxml 内容的新阶段,请再次查看答案。
    【解决方案2】:

    对于小型 FXML,Sebastian 的解决方案很好,但如果您在打开弹出窗口时遇到卡顿,可能是 FXML 太大或者您正在通过网络加载它。在这种情况下,FXMLLoader 将阻塞您的 GUI,因此您需要在后台执行 FXMLLoader。您可以使用为您的场景返回父级的服务,并在服务完成后创建场景和舞台。

    这是一个完整的例子:

    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.concurrent.Service;
    import javafx.concurrent.Task;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.fxml.FXMLLoader;
    import javafx.geometry.Pos;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ProgressIndicator;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        VBox vbox = new VBox(10);
        vbox.setAlignment(Pos.CENTER);
    
        final ProgressIndicator progress = new ProgressIndicator(-1);
        progress.setVisible(false);
    
        Button button = new Button("Open fxml");
        button.setOnAction(new EventHandler<ActionEvent>() {            
            @Override
            public void handle(ActionEvent event) {
                final Service<Parent> service = new Service<Parent>() {                 
                    @Override
                    protected Task<Parent> createTask() {   
                        return new Task<Parent>() {                         
                            @Override
                            protected Parent call() throws Exception {
                                //Out of FX Thread
                                String fxml = "/FxmlTest.fxml";
                                Parent root = FXMLLoader.load(getClass().getResource(fxml));
                                return root;
                            }
                        };
                    }
                };
                progress.visibleProperty().bind(service.runningProperty());
                service.start();
                service.runningProperty().addListener(new ChangeListener<Boolean>() {
                    @Override
                    public void changed(ObservableValue<? extends Boolean> value, Boolean oldValue, Boolean newValue) {                 
                        if(!newValue){//The service has ended
                            //In the FX Thread
                            Stage stage = new Stage();
                            Scene scene = new Scene(service.getValue());
                            stage.setScene(scene);
                            stage.show();
                        }
                    }
                });
            }
        });
    
        vbox.getChildren().addAll(button, progress);
    
        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
    }
    

    我放置了一个进度指示器来显示服务在加载时可能需要一些时间。

    如果你想检查它在 FX Thread 中的位置,你只需要使用 Platform.isFxApplicationThread()。

    希望对你有帮助。

    【讨论】:

    • 我正在尝试运行您的示例,但在最终 Service service = new Service() 中出现错误,它显示类型 Service 不接受参数
    • 你在使用 javafx.concurrent.Service 吗?我刚刚用我正在使用的导入编辑了答案。推荐你看一下并发javafx 2教程docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
    • 总的来说,我不同意这种解决方案,从本地资源加载 fxml 通常会非常快 - 只有当您通过网络加载时,性能才会慢到足以保证使用任务或服务。
    • 我想如果 FXML 很小就没有问题。但有时我在加载带有很多组件的 FXML 时遇到了一些冻结。当您按下按钮时,什么也没有发生,并且在弹出窗口加载时您什么也看不到,实际上 GUI 它被冻结了。所以我想对于这种情况,这个解决方案不是一个糟糕的解决方案。我还修改了我的答案,除了你提出的例外情况。谢谢,干杯。
    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2016-08-13
    • 2016-09-05
    相关资源
    最近更新 更多