在场景之后:
JavaFxMainApp JavaFXUpdaterApp
两者都是带有GUI和void main()方法的JavaFX应用程序。
Updater必须能够通过访问来启动JavaFXMainApp JavaFxMainApp.jar只知道主类 - >它只能!呼叫 main()中。
JavaFxMainApp也必须能够通过启动自行运行 main()中。
我无法启动多个VMS,这两个应用程序无法通信。
问题是:
Application.launch()每个JVM只能执行一次。
启动应用的标准javaFx方式:
Updater + MainApp
public static void main(String[] args) {
launch(args);
}
这里不可能满足要求1)。因为两个main()方法都调用launch()。
我找到的第二种方法是:
Updater + MainApp
public static void main(String[] args) {
Application app2 = JavaFxMainApp.class.newInstance();
Stage anotherStage = new Stage();
app2.start(anotherStage);
}
首先,我失去了传递args的可能性,但是我可以忍受它,因为它们不会被使用。 这里的主要问题是,如果JVM已经运行了JavaFx线程,则此代码仅起作用,因此它要求在之前的某个时刻在JVM中调用launch()。情况并非如此,因为两个调用都不再是launch()。
混合方法:
Updater calls launch(), MainApp takes the second approach
要求2)无法实现,现在无法在没有启动器更新程序的情况下启动MainApp。
我有另外一个想法肮脏"尝试launch()catch() - >尝试在两个应用程序中使用第二种方法(),但这会使两个应用程序结合并使设置不那么灵活。
有没有办法在不必覆盖JavaFxs的情况下实现这一目标。 LauncherImpl或Application类是否符合这些需求?
答案 0 :(得分:3)
你能做这样的事吗:
public class MainApp extends Application {
private Parent uiContent ;
public static final double DEFAULT_WIDTH = 800 ;
public static final double DEFAULT_HEIGHT = 600 ;
public Parent getContent() {
if (uiContent == null) {
uiContent = initializeUI();
}
return uiContent ;
}
public Scene createScene() {
return new Scene(getContent(), DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
public void initializeAndShowStage(Stage stage) {
stage.setScene(createScene());
stage.show();
}
private Parent initializeUI() {
// probably wise to check we are on the FX Application thread here...
Pane root = ... ;
// build ui....
return root ;
}
@Override
public void start(Stage primaryStage) throws Exception {
initializeAndShowStage(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}
和
public class UpdaterApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// whatever you need to launch the updater app here...
}
// invoke from the FX Application Thread to "start" main app:
private void showMainApp(Stage stage) {
MainApp app = new MainApp();
app.initializeAndShowStage(stage);
}
private void showMainApp() {
showMainApp(new Stage());
}
public static void main(String[] args) {
launch(args);
}
}
这将是最受欢迎的方法。如果您有强制要求main
的要求,那么您可以尝试这样的事情:
public class MainApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// .... build UI etc
}
public static void main(String[] args) throws Exception {
if (Platform.isFXApplicationThread()) {
Stage someStage = new Stage();
MainApp app = new MainApp();
app.start(stage);
} else {
launch(args);
}
}
}
然后您的更新程序应用程序只能从FX应用程序主题调用MainApp().main(new String[0]));
。
这感觉有点像黑客。
答案 1 :(得分:3)
您希望您的MainApp自己启动,并且您还希望UpdateApp在需要时启动MainApp,然后您可以按照我的步骤操作。我试过了,这个模型正在运作。
这是起点。您需要调用此类来开始您的应用程序
public class StartAnApp {
public static void main(String[] args){
new Thread(new MainApp()).start(); // this will call your MainApp
}
}
这是第一个将开始的应用程序。至于启动JavaFX应用程序,您需要有一个main()方法。因此,请确保在此课程中提供主要方法。
public class MainApp extends Application implements Runnable{
public MainApp(){} // constructor
@Override
public void start(Stage stage){
Text text = new Text("MainApp");
Button startUpdate = new Button("Start Update");
// When this button is pressed. It will launch UpdateApp Application
startUpdate.setOnAction( e -> {
Platform.runLater(new Runnable(){
@Override
public void run(){
new UpdateApp().start(new Stage());
}
});
});
Group root = new Group(text);
Scene scene = new Scene(root,300,400);
stage.setScene(scene);
stage.setX(0);
stage.setY(0);
stage.show();
}
// This method will be used when you first start an Application for
// which main method is required
public static void main(String[] args){
launch(args);
}
// This will be used when you call this Application from another JavaFX application
// if you have closed this application before
@Override
public void run(){
launch();
}
}
这是您的UpdateApp。此方法没有main()方法。
public class UpdateApp extends Application implements Runnable{
public UpdateApp(){} // constructor
@Override
public void start(Stage stage){
Text text = new Text("UpdateApp");
Button startAnother = new Button("Start Another");
// When this button is pressed. It will launch MainApp Application or you can add any other JavaApplication
startAnother.setOnAction( e -> {
Platform.runLater(new Runnable(){
@Override
public void run(){
new MainApp().start(new Stage());
}
});
});
Group root = new Group(text);
Scene scene = new Scene(root,300,400);
stage.setScene(scene);
stage.setX(350);
stage.setY(0);
stage.show();
}
// This will be used when you call this Application from another JavaFX application
@Override
public void run(){
launch();
}
}