JavaFx не позволяет клиенту запускать приложение несколько раз - PullRequest
0 голосов
/ 19 апреля 2020

Я хочу, чтобы клиент не запускал приложение несколько раз. Я думал о реализации Singleton Pattern.

public class MyClass extends Application {

private static MyClass app = null;

private MyClass (){
    super();   
}

public static MyClass getInstance(){
    if(app == null){
    app = new MyClass();
    }
    return app; 
}

@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLLogin.fxml"));
    Scene scene = new Scene(root);
    scene.setFill(Color.TRANSPARENT);
    primaryStage.initStyle(StageStyle.TRANSPARENT);
    primaryStage.setOpacity(0.95);
    primaryStage.setScene(scene);
    primaryStage.show();
}
public static void main(String[] args) {
    launch(args);
}
}

Однако, когда я запускаю приложение, появляется ошибка:

 Exception in Application constructor
 java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class  authentification.MyClass
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodException: authentification.MyClass.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$7(LauncherImpl.java:818)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
... 1 more
Exception running application authentification.MyClass

Может кто-нибудь объяснить мне, почему? и это идея Синглтона не так? Спасибо

1 Ответ

4 голосов
/ 19 апреля 2020

Жизненный цикл приложения JavaFX контролируется классом Application. Метод stati c Application.launch(...) запускает приложение; это достигается путем создания экземпляра класса Application (по умолчанию класс, из которого вызывается launch()), вызывающего конструктор без аргументов . Поскольку ваш одноэлементный подход делает конструктор без аргументов закрытым, процесс запуска больше не может создавать экземпляр вашего Application класса, и вы получаете показанное исключение.

Однако даже без этой проблемы создание приложения класс синглтон не достиг бы того, что вы хотите Используемый здесь шаблон синглтона просто гарантирует, что только один экземпляр класса может существовать в любой Java Виртуальной машине . Если пользователь запускает приложение во второй раз, он создает вторую JVM, которая может иметь собственный экземпляр вашего синглтона.

Чтобы гарантировать, что одновременно может работать только одно приложение, вам необходим механизм блокировки запуска приложений на уровне ОС. Один из подходов заключается в том, чтобы начать прослушивание указанного порта c при запуске и закрыть это соединение при завершении работы. Поскольку только одно приложение может прослушивать данный порт, это дает желаемый эффект. См., Например, JavaFX Single Instance Application .

...