如何在JavaFX中创建Singleton MainClass?

如何在JavaFX中创建Singleton MainClass?,java,singleton,javafx-2,Java,Singleton,Javafx 2,我想在中创建一个主类,但我遇到了困难,因为主类必须扩展,所以构造函数不能是私有的 我希望主类是一个单例类,因为我希望从任何类访问两个实例方法 在我当前的代码中,我将主类用作伪单例,因为我不保证该类不会在代码的某些部分再次实例化 我想知道,当您不能使用私有构造函数时,是否有一种体面的方法来创建单例 以下是我的主要课程代码: public final class MainClass extends Application { private static MainClass instance

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

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

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

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

以下是我的主要课程代码:

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);
    }
}

我认为添加一个如下所示的公共构造函数并删除
instance=thisstart
方法中的code>赋值就可以了,尽管我对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
”,但这将保证您不会多次运行构造函数来完成它。

@andrewhompson我想重新设计它,但我没有关于设计此类应用程序的最佳方法的手册。你能指出一个好的链接吗?实际上,现在的主要问题是如何获得我需要的窗口。也许有更好的方法来管理窗口。“如何获取我所需的窗口。”请参阅“谢谢@AndrewThompson”。但我没有使用多个“JFrames”。我只有一个顶部窗口,其余的是对话框。这正是我正在做的:“建立一个单一的主JFrame,然后让JDialog实例为其余的自由浮动元素显示,使用该框架作为对话框的父对象。”糟糕的是,有时我会在不完全清楚是否已经应用了正确的方法(如这里所示)的情况下抛出建议。术语“windows”让我不太清楚,因为它们可以是从
JWindow
到模态
JDialog
的任何东西。谢谢你的澄清祝你在技术问题上好运。没问题。我的文字描述对我的问题不是很好。现在更改为更清晰。无论如何,感谢您的评论,您提供的链接包含了一些关于如何在不使用对话框的情况下开发应用程序的好提示。我以后会尝试。它需要同步吗?只有在可能有多个线程调用此构造函数的情况下。假设两个线程同时调用
newmainclass()
,而
synchronized
块不存在。第一个线程可能会执行空检查,然后由于上下文切换而进入睡眠状态。第二个线程可能在第一个线程重新切换上下文之前进入并离开空检查,因此您将有两个
MainClass
实例浮动。
synchronized
块使这两个语句原子化,从而消除了竞争条件。感谢您的回答。由于构造函数必须是公共的,我认为这是唯一的方法。