如何在java中多次调用launch()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24320014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call launch() more than once in java
提问by venu
How to call the launch() more than once in java i am given an exception as "ERROR IN MAIN:java.lang.IllegalStateException: Application launch must not be called more than once"
如何在java中多次调用launch()我得到一个异常“主错误:java.lang.IllegalStateException:应用程序启动不能被调用多次”
I have create rest cleint in my java application when request comes it call javafx and opening webview after completing webview operarion am closing javafx windows using Platform.exit() method. when second request comes am getting this error how to reslove this error.
我在我的java应用程序中创建了rest cleint,当请求到来时它调用javafx并在完成webview操作后打开webview使用Platform.exit()方法关闭javafx窗口。当第二个请求出现时,我收到此错误如何解决此错误。
JavaFx Application Code:
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 Method: Calling to JavaFX application
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);
采纳答案by jewelsea
You can't call launch()
on a JavaFX application more than once, it's not allowed.
您不能launch()
多次调用JavaFX 应用程序,这是不允许的。
From the javadoc:
从javadoc:
It must not be called more than once or an exception will be thrown.
Suggestion for showing a window periodically
定期显示窗口的建议
- Just call
Application.launch()
once. - Keep the JavaFX runtime running in the background using
Platform.setImplicitExit(false)
, so that JavaFX does not shutdown automatically when you hide the last application window. - The next time you need another window, wrap the window
show()
call inPlatform.runLater()
, so that the call gets executed on the JavaFX application thread.
- 只打
Application.launch()
一次电话。 - 使用 保持 JavaFX 运行时在后台运行
Platform.setImplicitExit(false)
,以便在隐藏最后一个应用程序窗口时 JavaFX 不会自动关闭。 - 下次需要另一个窗口时,将窗口
show()
调用包装在中Platform.runLater()
,以便在 JavaFX 应用程序线程上执行该调用。
If you are mixing Swing you can use a JFXPanelinstead of an Application, but the usage pattern will be similar to that outlined above.
如果您混合使用 Swing,您可以使用JFXPanel而不是Application,但使用模式将类似于上面概述的模式。
Wumpus Sample
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);
}
}
Update, Jan 2020
2020 年 1 月更新
Java 9 added a new feature called Platform.startup()
, which you can use to trigger startup of the JavaFX runtime without defining a class derived from Application
and calling launch()
on it. Platform.startup()
has similar restrictions to the launch()
method (you cannot call Platform.startup()
more than once), so the elements of how it can be applied is similar to the launch()
discussion and Wumpus example in this answer.
Java 9 添加了一个名为 的新功能Platform.startup()
,您可以使用它来触发 JavaFX 运行时的启动,而无需定义派生自Application
和调用launch()
它的类。 Platform.startup()
对该launch()
方法有类似的限制(您不能Platform.startup()
多次调用),因此如何应用它的元素类似于launch()
本答案中的讨论和 Wumpus 示例。
For a demonstration on how Platform.startup()
can be used, see Fabian's answer to How to achieve JavaFX and non-JavaFX interaction?
有关如何Platform.startup()
使用的演示,请参阅 Fabian 对如何实现 JavaFX 和非 JavaFX 交互的回答?
回答by I B
try this, I tried this and found successful
试试这个,我试过这个,发现成功
@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();
}
}
回答by sergioFC
I use something like this, similar to other answers.
我使用这样的东西,类似于其他答案。
private static 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();
}
});
}
}