考虑一个现有的非fx应用程序,我们称它为Business。
Business公开了一个Model对象,而该对象又公开了一些属性。Model还接受这些属性的侦听器。
我的问题是将 JavaFx gui添加到这样的应用程序中。GuiApp显然扩展了javafx.application.Application,并将需要对Model对象的引用。
通过搜索将非字符串参数传递给GuiApp的解决方案,我发现了几种不同的方法:
Business在GuiApp中初始化对Model的静态引用。使用静力学的一个例子是here。Application。GuiApp初始化BusinessApp。这样的工作流的一个例子就是here。还有其他可行的方法吗?最佳实践?
发布于 2018-10-30 16:28:39
我将尝试演示在java程序和java程序之间传递引用的一些不同方法。
我张贴它,希望它将有助于一些未来的读者有类似的需要。我也希望它能鼓励其他的答案,以更多的解决办法。
张贴的代码不应被视为适当的实现,而应视为旨在澄清不同方法的简短代码。为此,我将介绍一个简单的侦听接口:
interface Observe{ void update(int i); }java类,表示退出的业务应用程序:
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应用程序,侦听该应用程序并充当视图:
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作为入口点,这是简单而直接的:
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:
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:
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应用程序中使用它:
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答案):
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;
}
}https://stackoverflow.com/questions/53003746
复制相似问题