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