开发者

Ignoring focusLost(), SWT.Verify, or other SWT listeners in Java code

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 imple开发者_C百科mented 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.


If you name the listener instead of using an anonymous one, you can add and remove it whenever you like.

Example:

 // Adding focus listener to textBox to wait for loss of focus to perform SQL statement.
 FocusAdapter focusTextBox = 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 ...
            }
  }
 };

You can then add the listener by doing this:

textBox.addFocusListener(focusTextBox);

Removal is as easy as this:

textBox.removeFocusListener(focusTextBox);

Just make sure to re-enable the listener after you've done what you've wanted to programmatically achieve, or your code will not act like you'd expect.


I didn't tested your code, but try method isFocusControl() in the listener to see if the user enters the text or you set the text with setText() when the focus is not in textBox.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜