PDA

View Full Version : [solved] KeyListener.componentKeyDown() immediately closes MessageBox.alert()



BinaryMuse
23 Mar 2009, 3:44 PM
Greetings, everyone,

I am creating a login dialog box similar to the one in the Mail application (via a class LoginDialog). I have several text fields, a login button, and a reset button. I am using a KeyListener.componentKeyDown() to capture the return key in any of the fields on the dialog and process onSubmit().

onSubmit() disables the form fields and checks to see if the user's credentials are valid; if they are not, it calls MessageBox.alert() with a third parameter of alertListener, a member of LoginDialog that checks to see if the "Ok" button was clicked, and if so, reenables the form fields.

The problem is that, when I press enter while the form fields have focus, the alert displays and immediately vanishes. If I change the code so that alertListener is not used, then multiple presses of enter can be captured while never closing the alert boxes that appear each time.

I have also tried this with KeyNav.onEnter() with similar results, except that I must do extra processing to make sure that the reset button wasn't the button that received the key press.

I have fiddled with using event.cancelBubble() to no avail, as well.

Is there something I'm doing wrong here? Is there an easier way to designate a button as the "default" button, so that the "enter" key processes it?


public class LoginDialog extends Dialog
{
protected StatusButtonBar buttonBar;
protected TextField<String> username;
protected TextField<String> password;
protected Button reset;
protected Button login;
protected SimpleComboBox<String> domain;
protected KeyListener keyListener;
protected WindowListener alertListener;

public LoginDialog()
{
// UI setup here ......

this.username = new TextField<String>();
this.username.setFieldLabel("Username");
this.add(this.username);

this.password = new TextField<String>();
this.password.setFieldLabel("Password");
this.password.setPassword(true);
this.add(this.password);

this.domain = new SimpleComboBox<String>();
this.domain.add("domain-name");
this.domain.add("Local");
this.domain.setFieldLabel("Domain");
this.domain.setSimpleValue("domain-name");
this.domain.setEditable(false);
this.add(this.domain);

KeyListener keyListener = new KeyListener() {
public void componentKeyDown(ComponentEvent event) {
if(event.getKeyCode() == 13)
{
onSubmit();
}
}
};

alertListener = new WindowListener() {
@Override
public void handleEvent(WindowEvent be)
{
if(be.buttonClicked.getText() == "Ok")
dismissError();
}
};

username.addKeyListener(keyListener);
password.addKeyListener(keyListener);
domain.addKeyListener(keyListener);

}

@Override
public void disable()
{
username.disable();
password.disable();
domain.disable();
buttonBar.disable();
}

@Override
public void enable()
{
username.enable();
password.enable();
domain.enable();
buttonBar.enable();
}

private void onSubmit()
{
disable();
buttonBar.getStatusBar().showBusy("Checking credentials...");

if(!validate())
{
buttonBar.getStatusBar().clear();
MessageBox.alert("Error", "You must enter a username and password.", alertListener);
return;
}

if(!checkCredentials())
{
buttonBar.getStatusBar().clear();
MessageBox.alert("Error", "Your username or password was incorrect.", alertListener);
return;
}
}

private void dismissError()
{
enable();
username.focus();
}
}

BinaryMuse
24 Mar 2009, 7:32 AM
After some further Googling, I was able to find a solution. The key is DeferredCommand (http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/index.html?com/google/gwt/user/client/DeferredCommand.html) provided by GWT:


This class allows you to execute code after all currently pending event handlers have completed, using the addCommand(Command) or addCommand(IncrementalCommand) methods. This is useful when you need to execute code outside of the context of the current stack.

private void onSubmit()
{
disable();
buttonBar.getStatusBar().showBusy("Checking credentials...");

if(!validate())
{
DeferredCommand.addCommand(new Command() {
public void execute() {
buttonBar.getStatusBar().clear();
MessageBox.alert("Error", "You must enter a username and password.", alertListener);
return;
}
});

}

/* code snipped */
}