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

时间:2014-06-20 04:33:25

标签: java javafx javafx-webengine

如何在java中多次调用launch()我被赋予异常" ERROR IN MAIN:java.lang.IllegalStateException:不能多次调用应用程序启动"

我在我的java应用程序中创建了rest cleint,当请求到来时,调用javafx并在完成webview operarion后使用Platform.exit()方法关闭javafx窗口时打开webview。当第二个请求收到此错误时如何重新发送此错误。

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);
    }

RestClient方法: 调用JavaFX应用程序

// method 1 to lanch javafx
javafx.application.Application.launch(AppWebview.class);

// method 2 to lanch javafx
String[] arguments = new String[] {"123"};
AppWebview .main(arguments);

3 个答案:

答案 0 :(得分:21)

您不能多次在JavaFX应用程序上调用launch(),这是不允许的。

来自javadoc:

It must not be called more than once or an exception will be thrown.

建议定期显示一个窗口

  1. 只需拨打Application.launch()一次即可。
  2. 使用Platform.setImplicitExit(false)在后台运行JavaFX运行时,以便在隐藏最后一个应用程序窗口时JavaFX不会自动关闭。
  3. 下次需要另一个窗口时,请在show()中包含窗口Platform.runLater(),以便在JavaFX应用程序线程上执行调用。
  4. 如果您要混合使用Swing,则可以使用JFXPanel代替Application,但使用模式与上述类似。

    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);
        }
    }
    

答案 1 :(得分:2)

试试这个,我试过这个并找到了成功的

@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();
    }
}

答案 2 :(得分:2)

我使用类似其他答案的东西。

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();
            }
        });
    }
}