Запустить приложение JavaFX из другого класса

Мне нужно запустить приложение javafx из другого класса "контейнер" и вызвать функции в приложении, но, похоже, не существует способа получить ссылку на приложение, запущенную с помощью Application.launch() метод. Это возможно? Благодаря

Ответ 1

У меня была та же проблема, что и у меня, и обошел ее, используя этот хак:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.util.concurrent.CountDownLatch;

public class StartUpTest extends Application {
    public static final CountDownLatch latch = new CountDownLatch(1);
    public static StartUpTest startUpTest = null;

    public static StartUpTest waitForStartUpTest() {
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return startUpTest;
    }

    public static void setStartUpTest(StartUpTest startUpTest0) {
        startUpTest = startUpTest0;
        latch.countDown();
    }

    public StartUpTest() {
        setStartUpTest(this);
    }

    public void printSomething() {
        System.out.println("You called a method on the application");
    }

    @Override
    public void start(Stage stage) throws Exception {
        BorderPane pane = new BorderPane();
        Scene scene = new Scene(pane, 500, 500);
        stage.setScene(scene);

        Label label = new Label("Hello");
        pane.setCenter(label);

        stage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

а затем класс, с которого вы запускаете приложение:

public class StartUpStartUpTest {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                javafx.application.Application.launch(StartUpTest.class);
            }
        }.start();
        StartUpTest startUpTest = StartUpTest.waitForStartUpTest();
        startUpTest.printSomething();
    }
}

Надеюсь, что это поможет.

Ответ 2

Предположим, что это наш класс JavaFX:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class OKButton extends Application {

    @Override
    public void start(Stage stage) {
        Button btn = new Button("OK");
        Scene scene = new Scene(btn, 200, 250);
        stage.setTitle("OK");
        stage.setScene(scene);
        stage.show();
    }
}

Затем мы можем запустить его из другого класса следующим образом:

import javafx.application.Application;

public class Main {
    public static void main(String[] args) {
        Application.launch(OKButton.class, args);
    }
}

Ответ 3

Вышеупомянутые способы вызова другого класса javafx из другого иногда работают. Стремление найти окончательный способ сделать это привело меня к следующей прогулке:

Предположим, что это класс javafx, который расширяет приложение, которое мы хотим показать из другого класса, тогда мы должны добавить следующие строки

class ClassToCall extends Application{

  //Create a class field of type Shape preferably static...

  static Stage classStage = new Stage();

  @Override
  public void start(Stage primaryStage){

  // Assign the class stage object to 
  // the method local Stage object:

   classStage = primaryStage ;

  // Here comes some more code that creates a nice GUI.....
   // ......
  } 

}

А теперь с другого места в проекте, чтобы открыть окно что созданный выше класс делает следующее:

    // Suppose we want to do it with a button clicked:

    btn1.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {

           //create an object of the class you wish to invoke its   
            //start() method:

            ClassToCall ctc = new ClassToCall();

          // Then call its start() method in the following way:

            ctc.start(ClassToCall.classStage);


       }// End handle(ActionEvent event)
     });// End anonymous class

Ответ 4

Запустите JavaFX в другом классе с помощью кнопки:

class Main extends Application{
 public void start(Stage s)throws Exception{
  event();
  s.show();
 }
 public void event(){
  btn.setOnAction(new EventHandler<ActionEvent>(){
   public void handle(ActionEvent ae){

    Stage s = new Stage();
    new SubClassName().start(s);

   }
  });

 }
public static void main(String[] args) {

        launch(args);

}
}

class SubClassName{
 public void start(Stage s){

  Pane pane = new Pane();
  Scene addFrame = new Scene(pane,280,450);

  s.setScene(addFrame);     
  s.show();

 }

}

Ответ 5

Я не уверен, чего вы пытаетесь достичь, но обратите внимание, что вы можете, например, позвонить из другого класса Application.launch, чтобы запустить поток приложений JavaFX и Platform.exit, чтобы остановить его.

Ответ 6

Я думаю, вы хотите сделать свой код чище и проще в управлении, а не иметь все в основном. Посмотрев пример для игры, я понял, что вы действительно можете запустить javaFX из другого класса. Он не запускает его из другого класса, но все же делает ваш код чище и проще в управлении. Вы могли бы, вероятно, изменить код ниже, чтобы расширить приложение на множество пакетов.

Для javaFX 11, который я использую, собран с openJDK 11. Вы можете просто отправить primaryStage в другой класс для инициализации и работы с ним как обычно. Вот пример кода. Не берите в голову название и прочее, я на самом деле использовал один и тот же код для написания своей программы. Если вы столкнулись с ошибкой, не стесняйтесь исправить ее самостоятельно:).... j/k.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class linkChecker extends Application {
    public static String title = "Link Checker";
    public static String version = "v0.00.01";

    @Override public void start(Stage primaryStage){
        app.stageInit(primaryStage);
        Scene scene = app.getScene();
        primaryStage.setTitle(title.concat(" - ").concat(version) );
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class app
{
    public static Stage primaryStage;

    public static void stageInit(Stage p){
        primaryStage = p;
    }

    public static Scene getScene(){
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override public void handle(ActionEvent event) {
                primaryStage.setWidth(500);
                primaryStage.setHeight(500);
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        Scene scene = new Scene(root, 1200, 800);

        return scene;
    }
}