我有一个gui,即添加了一个登录提示。
while(notValidLogIn){
LoginPrompt.getDetails() //a static method that
}
但是,loginPrompt是一个Jdialog,具有父JFrame。如何停止取消单击的循环,我可以将System.exit(0)置于取消操作中执行。但是我不想阻止一切,我想要这样的东西:
while(notValidLogIn && LoginPrompt.isNotCancelled()){
LoginPrompt.getDetails(); //a static method that creates an instance of login JDialog()
}
答案 0 :(得分:1)
while(notValidLogIn && LoginPrompt.isNotCancelled()){
LoginPrompt.getDetails(); //a static method that creates an instance of login JDialog()
}
如果此循环位于除EDT(事件调度线程)之外的另一个线程内,则可以使用SwingUtilities.invokeAndWait(new Runnable())
函数:invokeAndWait()
阻止当前线程,直到EDT完成执行由它。当我们想要等待执行线程以使用JDialogue/JFileChooser
等来获取用户或其他输入的确认时,特别使用此选项
while(notValidLogIn && LoginPrompt.isNotCancelled()){
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
LoginPrompt.getDetails() ;
}
});
}
注意: 重申强调:您应该确保此循环在另一个Thread内执行:例如使用Runnable
的扩展类,或通过匿名类:
new Thread()
{
// other code of your context
public void run()
{
while(notValidLogIn && LoginPrompt.isNotCancelled()){
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
LoginPrompt.getDetails() ;
}
});
}
}
}.start();
答案 1 :(得分:1)
在我最近的一个项目中,我实施了一个基于事件的解决方案。这个想法是JDialog
通知其父JFrame
登录过程如何进行,最后一个可能会或可能不会继续执行。这样我就没有循环并且保持不同的职责:模式将是这样的:
这是事件本身。没那么复杂:
class LoginEvent extends EventObject {
public static final int LOGIN_SUCCEEDED = 0;
public static final int LOGIN_FAILED = 1;
public static final int LOGIN_DIALOG_CLOSED = 2;
private int id;
public LoginEvent(Object source, int id) {
super(source);
this.id = id;
}
public int getId() {
return id;
}
}
处理这些LoginEvent
的接口:
public interface LoginListener extends EventListener {
public void handleLoginEvent(LoginEvent evt);
}
此课程必须保留List
订阅LoginListeners
:
class LoginDialog {
List<LoginListener> listeners = new ArrayList<>();
JDialog dialog;
JButton accept;
JButton cancel;
public void show() {
//create and show GUI components
}
public void close() {
if(dialog != null) {
dialog.dispose();
}
}
...
public void addLoginListener(LoginListener loginEventListener) {
if(!listeners.contains(loginEventListener)) {
listeners.add(loginEventListener);
}
}
public void removeLoginListener(LoginListener loginEventListener) {
listeners.remove(loginEventListener);
}
public void dispatchLoginEvent(LoginEvent evt) {
for(LoginListener loginListener: listeners) {
loginListener.handleLoginEvent(evt);
}
}
}
向accept
和cancel
按钮添加动作侦听器:
accept.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// validate login data
if(loginValid) {
dispatchLoginEvent(new LoginEvent(dialog, LoginEvent.LOGIN_SUCCEEDED));
} else {
dispatchLoginEvent(new LoginEvent(dialog, LoginEvent.LOGIN_FAILED));
}
}
});
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispatchLoginEvent(new LoginEvent(dialog, LoginEvent.LOGIN_DIALOG_CLOSED));
}
});
在JFrame
:
final LoginDialog dialog = new LoginDialog();
dialog.addLoginListener(new LoginListener() {
@Override
public void handleLoginEvent(LoginEvent evt) {
if(evt.getId() == LoginEvent.LOGIN_SUCCEEDED {
dialog.close();
//continue execution
return;
}
if(evt.getId() == LoginEvent.LOGIN_FAILED) {
JOptionPane.showMessageDialog(null, "Login failed!");
return;
}
if(evt.getId() == LoginEvent.CLOSE_LOGIN_DIALOG) {
dialog.close();
// do something when this dialog is closed
}
}
};
dialog.show();