In a recent project I was working on, I've implemented an event based solution. The idea is JDialog
notify to its parent JFrame
how the login process went and this last one may or may not continue its execution. This way I have no loops and keep separate responsibilities: The schema would be something like this:
LoginEvent:
This is the event itself. Not that complicated:
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
An interface to handle these LoginEvent
s:
public interface LoginListener extends EventListener {
public void handleLoginEvent(LoginEvent evt);
}
Login Dialog
This class has to mantain a List
with subscribed 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);
}
}
}
Adding action listeners to accept
and cancel
buttons:
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));
}
});
Subscribing a LoginListener
In your 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();