传递对javafx.application.Application的引用 [英] Passing reference to javafx.application.Application

查看:151
本文介绍了传递对javafx.application.Application的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个非fx现有应用程序,我们称之为 Business

Business 公开 Model 对象,该对象反过来暴露一些属性。 Model 也接受这些属性的侦听器。

Consider a non-fx existing application, let's call it Business.
Business exposes a Model object, which in turn exposes some properties. Model also accepts listeners to those properties.

我的问题是关于添加 JavaFx gui到这样的应用程序。 GuiApp 显然扩展了 javafx.application.Application ,并且需要引用模型对象。

My question is about adding JavaFx gui to such application. The GuiApp obviously extends javafx.application.Application and will need a reference to a Model object.

搜索将非String参数传递给 GuiApp 的解决方案我发现了几种不同的方法:

Searching for a solution for passing a non-String parameter to GuiApp I found several different approaches :


  • 静态方法:例如有 Business 初始化静态在 GuiApp 中引用 Model 。可以在此处查看使用静力学的一个示例。

  • JavaFx 9方法:如此处所示,您可以启动JavaFx应用程序没有扩展应用程序

  • 更改工作流程方法:将现有工作流程更改为 GuiApp 初始化 BussinessApp 此处可以看到此类工作流程的一个示例。

  • Static approach : for example have Business initialize a static reference to Model in GuiApp. One example of the use of statics can be seen here .
  • JavaFx 9 approach: as demonstrated here you can launch JavaFx application without extending Application.
  • Change workflow approach: change the existing workflow to have GuiApp initialize BussinessApp . One example of such workflow can be seen here.

还有其他可行方法吗?最佳实践 ?

Are there another viable approaches ? Best practice ?

推荐答案

我将尝试演示一些在java程序和java-fx程序之间传递引用的不同方法。

我发布它希望它能帮助一些有类似需求的未来读者。我也希望它可以通过其他解决方案鼓励其他答案。

发布的代码不应被视为正确的实现,而是一个旨在澄清不同方法的简短代码。为此,我将介绍一个简单的监听界面:

I'll try to demonstrate some different approaches for passing a reference between a java program, and a java-fx program.
I post it in hope it will help some future readers having similar need. I also hope it may encourage other answers with additional solutions.
The posted code should not be considered proper implementation, but rather a short code aiming to clarify the different approaches. For this purpose I'll introduce a simple listening interface :

interface Observe{ void update(int i); }

一个java类,代表一个现有的业务应用程序:

A java class, that represents an exiting business application :

public class JavaApp {

    private Observe observer;  private int counter = 0;

    JavaApp(Observe observer){  //not null safe
        this.observer = observer;
    }

    void process() {            
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                observer.update(counter >=100 ? 0 : ++counter);
            }
        }, 1000,1000);
    }
}

一个java-fx应用程序应添加到现有业务应用程序,监听它并作为视图:

A java-fx application that should be added to the existing business application, listen to it and serve as view:

public class JavaFxApp extends Application implements Observe{

    private Label label;

    @Override public void start(Stage stage) {
        label = new Label("waiting");
        BorderPane pane = new BorderPane(label);
        Scene scene = new Scene(pane, 100, 100);
        stage.setScene(scene);
        stage.show();
    }

    @Override public void update(int i) {
        Platform.runLater(()-> label.setText(String.valueOf(i)));
    }
}

我们如何分享参考资料,这种情况是对两个应用程序之间的 Observe 实例的引用?

How do we share a reference, in this case a reference to Observe instance, between the two applications ?

方法1 :将 start()方法视为应用程序的入口点(请参阅James_D 回答

如果你想将现有的java应用程序与java-fx绑定并使用java-fx Application <,这很简单直接/ code>作为入口点:

Approach 1: Consider the start() method as the entry point to the application (see James_D answer)
This is simple and straight forward if you want to tie the existing java application with java-fx and use java-fx Application as the entry point:

public class JavaFxApp extends Application implements Observe{

    private Label label;

    @Override public void start(Stage stage) {  
        JavaApp main = new JavaApp(this);
        label = new Label("waiting");
        BorderPane pane = new BorderPane(label);
        Scene scene = new Scene(pane, 100, 100);
        stage.setScene(scene);
        stage.show();

        new Thread(()-> { main.process();}).start(); //launch the business process
    }

    @Override   public void update(int i) {
        Platform.runLater(()-> label.setText(String.valueOf(i)));
    }

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



方法2:使用JavaFX 9平台#rebove

当你不能使用 Application #start 方法作为应用程序的入口点。

如fabians所示回答 ,关闭java-fx 9,您可以在不扩展应用程序的情况下启动。您所要做的就是修改java应用程序的 main


Approach 2: Use JavaFX 9 Platform#startup
This is the best solution I found, when you can not use the Application#start method as the entry point to the application.
As demonstrated in fabians answer, as off java-fx 9 you can launch without extending Application. All you have to do is modify the main of the java application:

public class JavaApp {

    private Observe observer;  private int counter = 0;

    JavaApp(Observe observer){//not null safe
        this.observer = observer;
    }

    void process() {
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override   public void run() {
                observer.update(counter >=100 ? 0 : ++counter);
            }
        }, 1000,1000);
    }

    public static void main(String[] args) {
        JavaFxApp view = new JavaFxApp(); //initialize JavaFx application
        JavaApp main = new JavaApp(view);

        Platform.startup(() -> {//launch JavaFx application 

            Stage stage = new Stage();
            try {
                view.start(stage);
            } catch (Exception ex) {ex.printStackTrace();}
        });

        main.process(); //run business process 
    }
}



方法3:使用静态成员

例如在java-fx应用程序中引入静态getter:


Approach 3: Use Static members
For example introduce a static getter in the java-fx application :

public class JavaFxApp extends Application {

    private static Label label = new Label("waiting");

    @Override public void start(Stage stage) {  
        BorderPane pane = new BorderPane(label);
        Scene scene = new Scene(pane, 100, 100);
        stage.setScene(scene);
        stage.show();
    }

    static Observe getObserver() {
        return JavaFxApp::update;
    }

    private static void update(int i) {
        Platform.runLater(()-> label.setText(String.valueOf(i)));
    }
}

并在java应用程序中使用它:

and use it in the java application:

public class JavaApp {

    private Observe observer;  private int counter = 0;

    JavaApp(Observe observer){//not null safe
        this.observer = observer;
    }

    void process() {
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                observer.update(counter >=100 ? 0 : ++counter);
            }
        }, 1000,1000);
    }

    public static void main(String[] args){
        new Thread(()-> Application.launch(JavaFxApp.class)).start();
        Observe observer = JavaFxApp.getObserver(); //get static observer reference
        JavaApp main = new JavaApp(observer);
        main.process();
    }
}

获得静态参考的更好方法可能是(基于答案):

A better approach to get a static reference might be (based on this answer) :

public class JavaFxApp extends Application implements Observe{

    private static final CountDownLatch latch = new CountDownLatch(1);
    private static Observe observer = null;
    private Label label;

   @Override public void init() {
       observer = this;
       latch.countDown();
    }

    @Override public void start(Stage stage){
        label = new Label("waiting");
        BorderPane pane = new BorderPane(label);
        Scene scene = new Scene(pane, 100, 100);
        stage.setScene(scene);
        stage.show();
    }

    @Override public void update(int i) {
        Platform.runLater(()-> label.setText(String.valueOf(i)));
    }

    static Observe getObserver() {
        try {
            latch.await();
        } catch (InterruptedException e) { e.printStackTrace();  }

        return observer;
    }
}

这篇关于传递对javafx.application.Application的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆