1

我想在JavaFX中创建一个Singleton主类,但我遇到了困难,因为主类必须扩展Application,所以构造函数不能是私有的。

我希望主类是单例,因为我想从任何类访问几个实例方法。

在我当前的代码中,我将主类用作假单例,因为我不保证不会在代码的某些部分再次实例化该类。

我想知道当您不能使用私有构造函数时是否有一种体面的方法来创建单例。

这是我的主要课程的代码:

public final class MainClass extends Application {
    private static MainClass instance;
    private Stage primaryStage, optionsStage;

    @Override
    public void start(final Stage primaryStage) {
        instance = this;
        try {

            // Main scene.
            {
                Parent page = (Parent) FXMLLoader.load(
                        MainWindowController.class.getResource("main.fxml"));
                Scene mainScene = new Scene(page);
                primaryStage.setScene(mainScene);
                primaryStage.show();
            }

            // Options scene.
            {
                optionsStage = new Stage();
                optionsStage.setTitle("Options");
                optionsStage.setResizable(false);
                optionsStage.initModality(Modality.APPLICATION_MODAL);
                optionsStage.initOwner(primaryStage);

                Parent page = (Parent) FXMLLoader.load(
                        OptionsWindowController.class.getResource("options.fxml"));
                Scene scene = new Scene(page);
                optionsStage.setScene(scene);
            }

        } catch (Exception ex) {
            Constants.LOGGER.log(Level.SEVERE, ex.toString());
        }
    }

    /**
     * Returns the instance of this class.
     * @return
     */
    public static MainClass getInstance() {
        return instance;
    }

    public Stage getPrimaryStage() {
        return primaryStage;
    }

    /**
     * Returns the options stage.
     * @return
     */
    public Stage getOptionsStage() {
        return optionsStage;
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX
     * application. main() serves only as fallback in case the
     * application can not be launched through deployment artifacts,
     * e.g., in IDEs with limited FX support. NetBeans ignores main().
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}
4

1 回答 1

4

我认为添加如下所示的公共构造函数并删除方法中的instance = this;赋值start就可以了,尽管我并不精通 JavaFX。我认为它不会多次尝试实例化你的主类,但如果 API 没有做出这样的保证,你可能会在以后遇到麻烦。

无论如何...如果您执行以下操作,您会很快发现:

public MainClass(){
    super();
    synchronized(MainClass.class){
        if(instance != null) throw new UnsupportedOperationException(
                getClass()+" is singleton but constructor called more than once");
        instance = this;
    }
}

NetBeans 的编译器(如果您正在使用它)会抱怨“泄漏this”,但这将保证您不会多次运行构造函数来完成。

于 2012-12-19T00:47:17.980 回答