Ignoring focusLost(), SWT.Verify, or other SWT listeners in Java code.
- by Zoot
Outside of the actual SWT listener, is there any way to ignore a listener via code?
For example, I have a java program that implements SWT Text Widgets, and the widgets have:
SWT.Verify listeners to filter out unwanted text input.
ModifyListeners to wait for the correct number of valid input characters and automatically set focus (using setFocus())to the next valid field, skipping the other text widgets in the tab order.
focusLost(FocusEvent) FocusListeners that wait for the loss of focus from the text widget to perform additional input verification and execute an SQL query based on the user input.
The issue I run into is clearing the text widgets. One of the widgets has the format "####-##" (Four Numbers, a hyphen, then two numbers) and I have implemented this listener, which is a modified version of SWT Snippet Snippet179. The initial text for this text widget is " - " to provide visual feedback to the user as to the expected format. Only numbers are acceptable input, and the program automatically skips past the hyphen at the appropriate point.
/*
* This listener was adapted from the "verify input in a template (YYYY/MM/DD)" SWT Code
* Snippet (also known as Snippet179), from the Snippets page of the SWT Project.
* SWT Code Snippets can be found at:
* http://www.eclipse.org/swt/snippets/
*/
textBox.addListener(SWT.Verify, new Listener()
{
boolean ignore;
public void handleEvent(Event e)
{
if (ignore) return;
e.doit = false;
StringBuffer buffer = new StringBuffer(e.text);
char[] chars = new char[buffer.length()];
buffer.getChars(0, chars.length, chars, 0);
if (e.character == '\b')
{
for (int i = e.start; i < e.end; i++)
{
switch (i)
{
case 0: /* [x]xxx-xx */
case 1: /* x[x]xx-xx */
case 2: /* xx[x]x-xx */
case 3: /* xxx[x]-xx */
case 5: /* xxxx-[x]x */
case 6: /* xxxx-x[x] */
{
buffer.append(' ');
break;
}
case 4: /* xxxx[-]xx */
{
buffer.append('-');
break;
}
default:
return;
}
}
textBox.setSelection(e.start, e.start + buffer.length());
ignore = true;
textBox.insert(buffer.toString());
ignore = false;
textBox.setSelection(e.start, e.start);
return;
}
int start = e.start;
if (start > 6) return;
int index = 0;
for (int i = 0; i < chars.length; i++)
{
if (start + index == 4)
{
if (chars[i] == '-')
{
index++;
continue;
}
buffer.insert(index++, '-');
}
if (chars[i] < '0' || '9' < chars[i]) return;
index++;
}
String newText = buffer.toString();
int length = newText.length();
textBox.setSelection(e.start, e.start + length);
ignore = true;
textBox.insert(newText);
ignore = false;
/*
* After a valid key press, verifying if the input is completed
* and passing the cursor to the next text box.
*/
if (7 == textBox.getCaretPosition())
{
/*
* Attempting to change the text after receiving a known valid input that has no results (0000-00).
*/
if ("0000-00".equals(textBox.getText()))
{
// "0000-00" is the special "Erase Me" code for these text boxes.
ignore = true;
textBox.setText(" - ");
ignore = false;
}
// Changing focus to a different textBox by using "setFocus()" method.
differentTextBox.setFocus();
}
}
}
);
As you can see, the only method I've figured out to clear this text widget from a different point in the code is by assigning "0000-00"
textBox.setText("000000")
and checking for that input in the listener. When that input is received, the listener changes the text back to " - " (four spaces, a hyphen, then two spaces).
There is also a focusLost Listener that parses this text widget for spaces, then in order to avoid unnecessary SQL queries, it clears/resets all fields if the input is invalid (i.e contains spaces).
// Adding focus listener to textBox to wait for loss of focus to perform SQL statement.
textBox.addFocusListener(new FocusAdapter()
{
@Override
public void focusLost(FocusEvent evt)
{
// Get the contents of otherTextBox and textBox. (otherTextBox must be <= textBox)
String boxFour = otherTextBox.getText();
String boxFive = textBox.getText();
// If either text box has spaces in it, don't perform the search.
if (boxFour.contains(" ") || boxFive.contains(" "))
{
// Don't perform SQL statements. Debug statement.
System.out.println("Tray Position input contains spaces. Ignoring.");
//Make all previous results invisible, if any.
labels.setVisible(false);
differentTextBox.setText("");
labelResults.setVisible(false);
}
else
{
//... Perform SQL statement ...
}
}
}
);
OK. Often, I use SWT MessageBox widgets in this code to communicate to the user, or wish to change the text widgets back to an empty state after verifying the input. The problem is that messageboxes seem to create a focusLost event, and using the .setText(string) method is subject to SWT.Verify listeners that are present on the text widget.
Any suggestions as to selectively ignoring these listeners in code, but keeping them present for all other user input?
Thank you in advance for your assistance.