Почему одна и та же основная функция после первого выполнения выполняется по-разному? - PullRequest
0 голосов
/ 05 мая 2020

В настоящее время я пишу приложение, в котором пользователям предоставляется экран входа в систему при запуске приложения. Этот экран входа в систему расширяет JDialog. В конце концов, пользователь может захотеть создать новый профиль, чтобы он мог открыть новый JDialog, в который он может вставить имя пользователя et c и снова выйти из него (закрытие окна вызывает dispose()). Он также может напрямую войти в систему и перенаправляется в JFrame, отображающий основное приложение, что приводит к закрытию маски входа с использованием dispose();.

Теперь фактическая проблема заключается в следующем: после входа в систему, возможно, что-то произошло в JFrame, который отображает основное приложение, и решаю выйти из системы, чтобы войти в систему, используя другую учетную запись. Я хочу запустить цикл приложения с самого начала, поэтому вызываю dispose() в JFrame, отображающем основное приложение и снова показывающим экран входа в систему . Однако я вижу, что основное приложение закрывается, как ожидалось, но экран входа в систему появляется только после встроенного тайм-аута входа в систему, что приводит к остановке всего приложения с помощью MessageDialog.

Я использую этот код в качестве своего пользовательского интерфейса. цикл в основном классе моего приложения (ApplicationCore.java):

public static int authTimeout = 0;
public static boolean applicationShutDownByUser = false;
public static boolean authorizationSuccessful = false;
public static boolean provideAccountCreation = false;
public static boolean returnToLogin = false;
private static PasStoreLogin loginMask;
private static final int MAX_TIMEOUT = 50; // 300 = 30 seconds

public static Toolkit toolkit = Toolkit.getDefaultToolkit();
public static int screenWidth = toolkit.getScreenSize().width;
public static int screenHeight = toolkit.getScreenSize().height;

public static Clipboard clipboard = toolkit.getSystemClipboard();

private static PasStoreUI frame;

public static void main(String[] args) {
    start();
}

public static void start() {

    applicationShutDownByUser = false;
    authorizationSuccessful = false;
    provideAccountCreation = false;
    authTimeout = 0;

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            loginMask = new PasStoreLogin();
        }
    });

    while (!authorizationSuccessful && authTimeout < MAX_TIMEOUT) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (provideAccountCreation) {
            if (PasStoreLogin.creationWizard == null) {
                PasStoreLogin.creationWizard = new ProfileCreationWizard();
            }
        } else {
            authTimeout++;
        }
    }

    if (authTimeout >= MAX_TIMEOUT && !applicationShutDownByUser) {
        JOptionPane.showMessageDialog(null, "Application shutting down! Login timeout reached.");
        loginMask.shutDown();
    }

    if (authorizationSuccessful) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame = new PasStoreUI("");
                frame.setVisible(true);
            }
        });
    }
}

public static void performLogout() {
    frame.dispose();
    start();
}

Чтобы запустить перезапуск приложения, я реализовал следующее в JFrame frame, который отображает основное приложение (PasStoreUI.java ):

    btnLogout.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            ApplicationCore.returnToLogin = true;
            ApplicationCore.performLogout();
        }
    });

Переменная returnToLogin внутри ApplicationCore была предназначена для запуска простого l oop метода start(), однако из-за врожденного поведения Java 's EventDispatchThread и, следовательно, EventQueue.invokeLater() простой do{//UIStuffSeenAbove}while(returnToLogin) l oop будет просто проигнорирован для переменной returnToLogin = false, так как он запускается сразу после вычисления if (authorizationSuccessful) и даже до создания JFrame. Установка начального значения от returnToLogin до true просто приведет к созданию второго экрана входа в систему сразу после входа в основное приложение.

Итак, как мне нужно спроектировать создание пользовательского интерфейса для решения этой проблемы? должным образом? Насколько я понимаю, текущая реализация заставляет все фреймы удаляться и создает новый экран входа в систему при вызове start(), который затем должен появиться сразу, а не после истечения времени ожидания входа в систему, потому что, когда я создаю приложение, это именно то, как приложение ведет себя - первое создание экрана входа в систему, второе запуск тайм-аута входа в систему, а не наоборот. Так есть ли какая-то конкретная c причина, по которой порядок выполнения меняется, когда я вызываю start() во второй раз?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...