В настоящее время я пишу приложение, в котором пользователям предоставляется экран входа в систему при запуске приложения. Этот экран входа в систему расширяет 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()
во второй раз?