【问题标题】:Launch JavaFX application from another class从另一个类启动 JavaFX 应用程序
【发布时间】:2014-09-16 16:17:35
【问题描述】:

我需要从另一个“容器”类启动 javafx 应用程序并调用应用程序上的函数,但似乎没有任何方法可以获取对使用 Application.launch() 启动的应用程序的引用方法。这可能吗? 谢谢

【问题讨论】:

    标签: javafx-8


    【解决方案1】:

    假设这是我们的 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);
        }
    }
    

    【讨论】:

    • 这是“从另一个类启动 JavaFX 应用程序”的一种简单易用的方法。但是,它不允许像 OP 想要的那样“获取对应用程序的引用”。
    • 如果你和我一样,并且不是直接从main() 运行,请使用new String[]{} 而不是args。它会像通常那样创建一个空数组。
    【解决方案2】:

    我遇到了与此相同的问题,并使用此 hack 解决了它:

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

    希望对你有所帮助。

    【讨论】:

    • 谢谢,效果很好。我还找到了另一种方法。如果您启动一个应用程序,那么只要您在应用程序线程上添加阶段,您就可以从代码库中的任何位置将阶段加载到其中。您可以为此使用 Platform.runLater()。
    • @Oli,你能发布一个其他方式的例子吗?我目前遇到了同样的问题。
    • 应用程序退出后如何让 printSomething() 方法执行?
    【解决方案3】:

    我不确定您要实现什么,但请注意,您可以例如从另一个类调用 Application.launch 来启动 JavaFX 应用程序线程并使用 Platform.exit 来停止它。

    【讨论】:

    • 谢谢,但 Application.launch() 是问题所在。它为我构建了我的应用程序,但不返回对它的引用或允许我将任何对象传递给应用程序的构造函数!是否有另一种方法可以在调用启动后获取构造的应用程序?
    • 你如何从另一个班级呼叫Application.launch()?我收到class [myclass] is not a subclass of javafx.application.Application 错误
    • @JohnADurston 方法重载。使用这个版本:docs.oracle.com/javase/8/javafx/api/javafx/application/…
    【解决方案4】:

    上述从另一个调用另一个 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's stage object to 
      // the method's 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
    

    【讨论】:

      【解决方案5】:

      使用 Button 在其他类中启动 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();
      
       }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-17
        • 2014-11-05
        • 2020-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多