首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >传递对javafx.application.Application的引用

传递对javafx.application.Application的引用
EN

Stack Overflow用户
提问于 2018-10-26 07:38:45
回答 1查看 791关注 0票数 1

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

Business公开了一个Model对象,而该对象又公开了一些属性。Model还接受这些属性的侦听器。

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

通过搜索将非字符串参数传递给GuiApp的解决方案,我发现了几种不同的方法:

  • 静态方法:例如,让BusinessGuiApp中初始化对Model的静态引用。使用静力学的一个例子是here
  • JavaFx 9方法:如here所示,您可以启动JavaFx应用程序,而无需扩展Application
  • 更改工作流方法:将现有工作流更改为让GuiApp初始化BusinessApp。这样的工作流的一个例子就是here

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-30 16:28:39

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

我张贴它,希望它将有助于一些未来的读者有类似的需要。我也希望它能鼓励其他的答案,以更多的解决办法。

张贴的代码不应被视为适当的实现,而应视为旨在澄清不同方法的简短代码。为此,我将介绍一个简单的侦听接口:

代码语言:javascript
复制
interface Observe{ void update(int i); }

java类,表示退出的业务应用程序:

代码语言:javascript
复制
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应用程序,侦听该应用程序并充当视图:

代码语言:javascript
复制
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实例的引用)?

start()方法1:将方法作为应用程序的入口点(参见James_D answer)

如果您想将现有的java应用程序与java绑定起来,并使用java Application作为入口点,这是简单而直接的:

代码语言:javascript
复制
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 Platform#startup

这是我找到的最好的解决方案,当不能时,可以使用Application#start方法作为应用程序的入口点。

正如法比亚斯answer中所展示的那样,可以在不扩展Application的情况下启动java 9。您要做的就是修改java应用程序的main

代码语言:javascript
复制
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应用程序中引入一个静态getter:

代码语言:javascript
复制
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应用程序中使用它:

代码语言:javascript
复制
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();
    }
}

获得静态引用的更好方法可能是(基于this答案):

代码语言:javascript
复制
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;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53003746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档