我有一个GUI,添加了登录提示。

while(notValidLogIn){
        LoginPrompt.getDetails() //a static method that
}


但是,loginPrompt是具有父JFrame的Jdialog。如何停止单击的取消循环,我可以将System.exit(0)置于执行的取消动作中。但是不想停止一切,我想要类似的东西:

while(notValidLogIn && LoginPrompt.isNotCancelled()){
  LoginPrompt.getDetails(); //a static method that creates an instance of login JDialog()
}

最佳答案

在我最近从事的项目中,我实现了一个基于事件的解决方案。这个想法是JDialog通知其父JFrame登录过程如何进行,而最后一个登录可能继续或可能不继续执行。这样,我就没有循环并保持各自的职责:模式将是这样的:

LoginEvent:

这是事件本身。没那么复杂:

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


LoginListener

处理这些LoginEvent的接口:

public interface LoginListener extends EventListener {

    public void handleLoginEvent(LoginEvent evt);

}


登录对话框

此类必须维护具有预订的ListLoginListeners

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


将动作侦听器添加到acceptcancel按钮:

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


订阅LoginListener

在您的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();

09-27 18:34