Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中多次调用launch()_Java_Javafx_Javafx Webengine - Fatal编程技术网

如何在java中多次调用launch()

如何在java中多次调用launch(),java,javafx,javafx-webengine,Java,Javafx,Javafx Webengine,如何在java中多次调用launch()我收到了一个异常“ERROR in MAIN:java.lang.IllegalStateException:Application launch不能被多次调用” 我已经在java应用程序中创建了rest cleint,当请求到来时,它调用javafx并在完成webview操作后打开webview。我正在使用Platform.exit()方法关闭javafx窗口。当第二个请求到来时,我得到了这个错误,如何重新爱上这个错误 JavaFx应用程序代码: pub

如何在java中多次调用launch()我收到了一个异常“ERROR in MAIN:java.lang.IllegalStateException:Application launch不能被多次调用”

我已经在java应用程序中创建了rest cleint,当请求到来时,它调用javafx并在完成webview操作后打开webview。我正在使用Platform.exit()方法关闭javafx窗口。当第二个请求到来时,我得到了这个错误,如何重新爱上这个错误

JavaFx应用程序代码:

public class AppWebview extends Application  {

    public static Stage stage;

    @Override
    public void start(Stage _stage) throws Exception {

        stage = _stage;
        StackPane root = new StackPane();

        WebView view = new WebView();

        WebEngine engine = view.getEngine();
        engine.load(PaymentServerRestAPI.BROWSER_URL);
        root.getChildren().add(view);
        engine.setJavaScriptEnabled(true);
        Scene scene = new Scene(root, 800, 600);
        stage.setScene(scene);

        engine.setOnResized(new EventHandler<WebEvent<Rectangle2D>>() {
            public void handle(WebEvent<Rectangle2D> ev) {
                Rectangle2D r = ev.getData();
                stage.setWidth(r.getWidth());
                stage.setHeight(r.getHeight());
            }
        });

        JSObject window = (JSObject) engine.executeScript("window");
        window.setMember("app", new BrowserApp());

        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
不能多次调用JavaFX应用程序,这是不允许的

从javadoc:

It must not be called more than once or an exception will be thrown.
定期显示窗口的建议

  • 只需调用一次
    Application.launch()
  • 使用保持JavaFX运行时在后台运行,以便在隐藏最后一个应用程序窗口时JavaFX不会自动关闭
  • 下次需要另一个窗口时,将窗口调用包装进来,以便在JavaFX应用程序线程上执行该调用
  • 如果您正在混合Swing,您可以使用a而不是,但是使用模式将与上面概述的类似

    Wumpus样本

    import javafx.animation.PauseTransition;
    import javafx.application.*;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    import java.util.*;
    
    // hunt the Wumpus....
    public class Wumpus extends Application {
        private static final Insets SAFETY_ZONE = new Insets(10);
        private Label cowerInFear = new Label();
        private Stage mainStage;
    
        @Override
        public void start(final Stage stage) {
            // wumpus rulez
            mainStage = stage;
            mainStage.setAlwaysOnTop(true);
    
            // the wumpus doesn't leave when the last stage is hidden.
            Platform.setImplicitExit(false);
    
            // the savage Wumpus will attack
            // in the background when we least expect
            // (at regular intervals ;-).
            Timer timer = new Timer();
            timer.schedule(new WumpusAttack(), 0, 5_000);
    
            // every time we cower in fear
            // from the last savage attack
            // the wumpus will hide two seconds later.
            cowerInFear.setPadding(SAFETY_ZONE);
            cowerInFear.textProperty().addListener((observable, oldValue, newValue) -> {
                PauseTransition pause = new PauseTransition(
                        Duration.seconds(2)
                );
                pause.setOnFinished(event -> stage.hide());
                pause.play();
            });
    
            // when we just can't take it  anymore,
            // a simple click will quiet the Wumpus,
            // but you have to be quick...
            cowerInFear.setOnMouseClicked(event -> {
                timer.cancel();
                Platform.exit();
            });
    
            stage.setScene(new Scene(cowerInFear));
        }
    
        // it's so scary...
        public class WumpusAttack extends TimerTask {
            private String[] attacks = {
                    "hugs you",
                    "reads you a bedtime story",
                    "sings you a lullaby",
                    "puts you to sleep"
            };
    
            // the restaurant at the end of the universe.
            private Random random = new Random(42);
    
            @Override
            public void run() {
                // use runlater when we mess with the scene graph,
                // so we don't cross the streams, as that would be bad.
                Platform.runLater(() -> {
                    cowerInFear.setText("The Wumpus " + nextAttack() + "!");
                    mainStage.sizeToScene();
                    mainStage.show();
                });
            }
    
            private String nextAttack() {
                return attacks[random.nextInt(attacks.length)];
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    更新,2020年1月

    Java9添加了一个名为的新特性,您可以使用该特性触发JavaFX运行时的启动,而无需定义从
    应用程序派生的类,并对其调用
    launch()
    Platform.startup()
    launch()
    方法有类似的限制(您不能多次调用
    Platform.startup()
    ),因此如何应用它的元素类似于此答案中的
    launch()
    讨论和Wumpus示例


    有关如何使用
    Platform.startup()
    的演示,请参阅Fabian的答案

    @Override
    public void start() {
        super.start();
        try {
                        // Because we need to init the JavaFX toolkit - which usually Application.launch does
                        // I'm not sure if this way of launching has any effect on anything
            new JFXPanel();
    
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    // Your class that extends Application
                    new ArtisanArmourerInterface().start(new Stage());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    我用了类似的方法,类似于其他答案

    private static volatile boolean javaFxLaunched = false;
    
    public static void myLaunch(Class<? extends Application> applicationClass) {
        if (!javaFxLaunched) { // First time
            Platform.setImplicitExit(false);
            new Thread(()->Application.launch(applicationClass)).start();
            javaFxLaunched = true;
        } else { // Next times
            Platform.runLater(()->{
                try {
                    Application application = applicationClass.newInstance();
                    Stage primaryStage = new Stage();
                    application.start(primaryStage);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
    
    private static volatile boolean javaFxLaunched=false;
    
    公共静态void myLaunch(Class@jewelsea你能给我这个示例代码吗?对于请求过程已完成,我想关闭窗口。我已经将这个示例代码添加到我的spring mvc项目中。请给我这个示例代码。@jewelsea请给我这个问题的示例代码。thanks@jewelsea非常感谢埃弗里发布的答案。但这对我来说不是有效的答案。我有个建议安装spring mvc应用程序并托管在我的服务器上。当服务器启动时,我也想启动java fx应用程序。我的一个spring模块将调用java fx应用程序传递url,然后java fx我需要在webview中显示该网页,在处理完该网页后,我需要将网页输出发送回spring mvc mobule,直到获得输出表单webpage spring将等待,我只需要使用一个线程来实现javafx功能。我的spring应用程序需要在任何时间点对javafx应用程序进行完全访问控制。再次感谢Wumpus示例既有用又有趣。谢谢!谢谢。在我的场景中,我使用
    Platform.setImplicitExit(false)解决了这个问题
    +
    Application.launch(ApplicationX.class)
    启动第一个应用程序+您的
    平台。对于我以后使用的应用程序,请稍后运行
    。这样我就不需要使用
    新的JFXPanel()
    对不起,但是这段代码在哪个类中?在
    AppWebview
    中?来源:@Nithin您是指
    应用程序的参数。启动(myClass)
    ?也许您可以使用一些以前的静态方法,如
    myClass.StaticMethodToUnit(值1,值2)
    @Nithin我不知道这与你的问题有什么关系。你仍然可以像你一样将参数传递给
    launch
    方法。非常感谢你,塞吉奥。我会看一看。我可以知道你每次调用myLaunch方法时是如何传递参数的吗?我不需要传递参数。你可以使用
    Application.launch(applicationClass,args)
    而不是
    Application.launch(applicationClass)
    ,但是我认为您不能在Platfor.runlater中传递参数谢谢您的更新!我们必须在应用程序中显式调用Platform.exit()来停止它吗?真的谢谢您!这个示例非常简单。
    private static volatile boolean javaFxLaunched = false;
    
    public static void myLaunch(Class<? extends Application> applicationClass) {
        if (!javaFxLaunched) { // First time
            Platform.setImplicitExit(false);
            new Thread(()->Application.launch(applicationClass)).start();
            javaFxLaunched = true;
        } else { // Next times
            Platform.runLater(()->{
                try {
                    Application application = applicationClass.newInstance();
                    Stage primaryStage = new Stage();
                    application.start(primaryStage);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }