Reputation: 47280
I have a gui, that is having a Login prompt added.
while(notValidLogIn){
LoginPrompt.getDetails() //a static method that
}
Hwoever, the loginPrompt is a Jdialog, with a parent JFrame. How can I stop looping of cancel clicked, I could put System.exit(0) in cancel action performed. But don't want to stop everything, I want something like :
while(notValidLogIn && LoginPrompt.isNotCancelled()){
LoginPrompt.getDetails(); //a static method that creates an instance of login JDialog()
}
Upvotes: 0
Views: 1236
Reputation: 17971
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:
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;
}
}
An interface to handle these LoginEvent
s:
public interface LoginListener extends EventListener {
public void handleLoginEvent(LoginEvent evt);
}
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));
}
});
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();
Upvotes: 1
Reputation: 15408
while(notValidLogIn && LoginPrompt.isNotCancelled()){
LoginPrompt.getDetails(); //a static method that creates an instance of login JDialog()
}
If this loop is inside another thread other than the EDT(event dispatch thread), then you can use SwingUtilities.invokeAndWait(new Runnable())
function: invokeAndWait()
blocks the current thread until the EDT is done executing the task given by it. This option is particularly used while we want to await an execution of a thread for taking confirmation from user or other input using JDialogue/JFileChooser
etc
while(notValidLogIn && LoginPrompt.isNotCancelled()){
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
LoginPrompt.getDetails() ;
}
});
}
Note: re-stating for emphasizing: you should ensure that this loop is executing inside another Thread: such as using an extended class of Runnable
, or by means of anonymous class:
new Thread()
{
// other code of your context
public void run()
{
while(notValidLogIn && LoginPrompt.isNotCancelled()){
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
LoginPrompt.getDetails() ;
}
});
}
}
}.start();
Upvotes: 1