Игнорирование focusLost (), SWT.Verify или других прослушивателей SWT в коде Java - PullRequest
0 голосов
/ 15 сентября 2010

Вне реального слушателя SWT, есть ли способ игнорировать слушателя через код?

Например, у меня есть Java-программа, которая реализует текстовые виджеты SWT, и виджеты имеют:

  • SWT. Проверяйте прослушиватели для фильтрации нежелательного ввода текста.
  • ModifyListeners для ожидания правильного количества допустимых входных символов и автоматической установки фокуса (с помощью setFocus ()) на следующее допустимое поле, пропуская другие текстовые виджеты в порядке табуляции.
  • focusLost (FocusEvent) FocusListeners, которыедождитесь потери фокуса от текстового виджета, чтобы выполнить дополнительную проверку ввода и выполнить SQL-запрос на основе пользовательского ввода.

Проблема, с которой я сталкиваюсь, - это очистка текстовых виджетов.Один из виджетов имеет формат "#### - ##" (четыре числа, дефис, затем два числа), и я реализовал этот прослушиватель, который является модифицированной версией фрагмента SWT Snippet179 .Исходный текст для этого текстового виджета - «-», чтобы предоставить пользователю визуальную обратную связь относительно ожидаемого формата.Допускается ввод только цифр, и программа автоматически пропускает дефис в соответствующей точке.

     /*
      * 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();
    }
   }
  }
  );

Как видите, единственный метод, который я выбрал, - очистить этот текстовый виджет из другой точки.в коде, присваивая "0000-00"

textBox.setText("000000")

и проверяя этот вход в слушателе.Когда этот входной сигнал получен, слушатель изменяет текст обратно на «-» (четыре пробела, дефис, затем два пробела).

Существует также слушатель focusLost, который анализирует этот текстовый виджет на наличие пробелов, затем вЧтобы избежать ненужных запросов SQL, он очищает / сбрасывает все поля, если ввод неверен (то есть содержит пробелы).

 // 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.Часто я использую виджеты SWT MessageBox в этом коде для связи с пользователем или желаю изменить текстовые виджеты обратно на пустое состояние после проверки ввода.Проблема в том, что почтовые ящики создают событие focusLost, а использование метода .setText (string) зависит от SWT.Verify слушателей, присутствующих в текстовом виджете.

Есть ли какие-либо предложения по избирательному игнорированию этих слушателей в коде, но сохранению их присутствия для всего остального пользовательского ввода?

Заранее благодарен за помощь.

Ответы [ 2 ]

2 голосов
/ 07 января 2011

Если вы называете слушателя вместо того, чтобы использовать анонимного, вы можете добавлять и удалять его в любое время.

Пример:

 // 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 ...
            }
  }
 };

Затем вы можете добавить слушателя следующим образом:

textBox.addFocusListener(focusTextBox);

Удаление так же просто, как это:

textBox.removeFocusListener(focusTextBox);

Просто убедитесь, что слушатель снова включен после того, как вы сделали то, что хотели достичь программным путем, иначе ваш код не будет работать так, как вы ожидаете.

1 голос
/ 16 сентября 2010

Я не проверял ваш код, но попробуйте метод isFocusControl() в слушателе, чтобы увидеть, вводит ли пользователь текст или вы установили текст с помощью setText(), когда фокус не в textBox.

...