对用户隐藏Javafx实现

时间:2019-06-10 06:03:23

标签: java javafx

因此,当前我正在开发一个项目,该项目需要在一个方法中启动一个快速的Javafx窗口。因为我不想让类扩展Application,所以我的解决方案是创建一个扩展应用程序的内部类,并通过创建内部类的实例并在内部类中调用launch来在方法内启动javafx窗口,如下所示

public void createWindow() {
    Fx window = new Fx();
    window.launchWindow();
}

public static class Fx extends Application {
    private void launchWindow() {
        launch();
    }

    public void start(Stage stage) {
        //javafx code
    }
}

问题在于内部类必须是公共的,因为javafx要求启动的类是公共的,否则它将引发异常。这导致用户现在可以在内部类公开时访问它。

是否可以将其设为私有或其他解决方法?还是我应该采取另一种方式做到这一点?

1 个答案:

答案 0 :(得分:7)

使用Application.launch并不是启动JavaFX运行时的唯一方法,它只是标准且使用最多的选项。另一种选择是使用Platform.startup(Runnable)(JavaFX 9+)。该方法将启动JavaFX运行时,并在 JavaFX Application Thread 上调用给定的Runnable

Platform.startup(() -> {
    Stage stage = new Stage();
    stage.setScene(/* your built scene */);
    stage.show();
});

此设置需要牢记一些重要事项:

  1. 每个JVM实例只能启动一次JavaFX运行时;第二次调用startup将导致IllegalStateException。如果您的方法可以被多次调用,那么您需要在第二次及以后的调用中使用Platform.runLater(Runnable)

  2. 在默认情况下,关闭最后一个Stage后,JavaFX运行时将退出。一旦发生这种情况,除非重新启动整个JVM,否则无法再次启动它。要阻止这种情况发生,请使用Platform.setImplicitExit(false)。现在,您将使用Platform.exit()来停止JavaFX运行时。

  3. 使用startup绕过正常的JavaFX生命周期。换句话说,将不会创建Application子类的实例,并且不会调用init()start(Stage)stop()方法。

    < / li>
  4. 如果应用程序的JavaFX部分不重要,请注意,只要应用程序存在,运行时将在启动后消耗资源。即使关闭了最后一个窗口(隐式出口已设置为false),也是如此。解决此问题的方法(可能很简单)是在另一个进程中启动JavaFX,该进程可以根据需要进行销毁。


如果您使用的是Java 9+,则另一个(或至少是免费的)选择是使用模块。将您的Application类放在仅导出到javafx.graphics模块的包中。这将阻止其他模块访问您的Application类(即使它是公共的)。

module app {
    requires javafx.graphics;
    exports com.example to javafx.graphics;
}

注意:这不会阻止人们使用类路径或使用--add-exports,但这将是“错误地使用您的库”,这意味着行为未指定。