Arhn - архитектура программирования

Бесконечный цикл фокусировки на текстовых полях

У меня есть 2 JTextFields:

JTextField txtJobType, txtPriorityCode;

Это функционал, который мне нужен:

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

private void txtJobTypeFocusLost(java.awt.event.FocusEvent evt) {                                     
    System.out.println("JobType Focus Lost");
    if (!checkFieldExists(txtJobType.getText(), "jobType", "jobCode",
            JobType.class) || txtJobType.getText().isEmpty()) {
        txtJobType.requestFocusInWindow();
        txtJobType.selectAll();
    } else {
    }
} 

Итак, если поле не существует или текст пуст, верните фокус на txtJobType и выделите весь текст (если есть)

Это работает без проблем. Однако у меня есть поле txtPriorityCode, которое должно вести себя точно так же. Так я и сделал:

private void txtPriorityCodeFocusLost(java.awt.event.FocusEvent evt) {                                          
    System.out.println("PriorityCode Focus Lost");
    if (!checkFieldExists(txtPriorityCode.getText(), "priority", "priorityCode",
            Priority.class) || txtPriorityCode.getText().isEmpty()) {
        txtPriorityCode.requestFocusInWindow();
        txtPriorityCode.selectAll();
    }
}

Вот здесь и начинается проблема: если пользователь оставляет jobType и вкладки переходит в Priority, тогда код пытается вернуть фокус обратно на тип задания, но, поскольку в этот момент приоритет также пуст, он попытается вернуть фокус обратно из типа задания, что приведет к этому результату. :

PriorityCode Focus Lost
JobType Focus Lost
PriorityCode Focus Lost
JobType Focus Lost

Любая помощь в том, как я могу реализовать это поведение, приветствуется, так как мне нужно сделать это как минимум для 10 других текстовых полей.

Спасибо!


  • не делайте так низкоуровневый, как FocusListener, вместо этого используйте InputVerifier 21.08.2012
  • @kleo: извините, я, должно быть, печатал свой ответ, когда вы печатали свой комментарий. Думаю, великие умы думают одинаково. 21.08.2012

Ответы:


1

Вы не должны возиться с потерей фокуса или другими низкоуровневыми конструкциями. Вместо этого, почему бы просто не использовать InputVerifier в соответствии с этим примером и это тоже?

Например, это может выглядеть примерно так:

import javax.swing.*;

public class InputVerifierEg {
   private JPanel mainPanel = new JPanel();
   private JTextField txtJobType = new JTextField(10);
   private JTextField txtPriorityCode = new JTextField(10);

   public InputVerifierEg() {
      txtJobType.setInputVerifier(new MyInputVerifier("jobType", "jobCode",
            JobType.class));
      txtPriorityCode.setInputVerifier(new MyInputVerifier("priority", "priorityCode",
            Priority.class));

      mainPanel.add(new JLabel("Job Type:"));
      mainPanel.add(txtJobType);
      mainPanel.add(Box.createHorizontalStrut(15));
      mainPanel.add(new JLabel("Priority Code:"));
      mainPanel.add(txtPriorityCode);

   }

   public JPanel getMainPanel() {
      return mainPanel;
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("InputVerifierEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new InputVerifierEg().getMainPanel());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyInputVerifier extends InputVerifier {
   private String fieldName;
   private String codeName;
   private Class<?> classType;

   public MyInputVerifier(String fieldName, String codeName, Class<?> classType) {
      this.fieldName = fieldName;
      this.codeName = codeName;
      this.classType = classType;
   }

   @Override
   public boolean verify(JComponent input) {
      JTextField tField = (JTextField) input;

      // assuming that the checkFieldExists is a static method of a utility class
      if (!FieldCheckerUtil.checkFieldExists(tField.getText(), fieldName,
            codeName, classType)) {
         return false;
      }

      if (tField.getText().trim().isEmpty()) {
         return false;
      }
      return true;
   }

   @Override
   public boolean shouldYieldFocus(JComponent input) {
      JTextField tField = (JTextField) input;

      if (verify(input)) {
         return true;
      } else {
         tField.selectAll();
         // show JOptionPane error message?
         return false;
      }
   }
}
21.08.2012
  • @kleo: должно быть, мы печатали одновременно. 21.08.2012
  • Это здорово и работает именно так, как мне нужно, за исключением одного: как мне реализовать проверку на наличие введенного текста в базе данных? Каждое текстовое поле связано с другим объектом, поэтому в моем методе focusLost вы можете видеть, как я передаю имена классов и таблиц Entity. Я не совсем понимаю, как я мог бы реализовать это в операторе MyInputVerifier if. 21.08.2012
  • @MetalWing: я не вижу в этом проблемы. Вы можете передать ту же информацию в конструктор вашего верификатора или использовать HashMap для хранения этой информации. 21.08.2012
  • @HovercraftFullOfEels, как бы глупо это ни звучало, есть ли шанс продемонстрировать мне концепцию? Я вижу, что public boolean verify(JComponent input) { — это то место, где я бы сделал его public boolean verify(JComponent input , String tableField, Class entityClass), но как мне передать разные классы для каждого текстового поля в конструкторе? 21.08.2012
  • @Metal: но обратите внимание, что передача типа класса в параметр метода придает коду неприятный запах. Я подозреваю, что код был бы намного чище, если бы вместо этого вы использовали дженерики. 22.08.2012

  • 2

    Лично я ненавижу, когда проверка выполняется таким образом и мешает мне перемещать поля в форме так, как я считаю нужным. Почему бы не выполнить проверку всех полей при отправке формы и не выделить недействительные в это время?

    21.08.2012
  • Я не работал со свингом в течение некоторого времени, но возможно ли иметь один метод focusLost, который внутренне проверяет, какое поле потеряло фокус, и возвращает фокус этому полю, когда проверка не удалась? 21.08.2012

  • 3

    Может быть, сделать одну проверку:

    txtPriorityCode.getText().isEmpty()
    

    А затем, с другой стороны, проверьте, если:

    !txtPriorityCode.getText().isEmpty() && txtJobType.getText().isEmpty()
    

    т. е. выполнять проверку второго только в том случае, если первый не пуст.

    21.08.2012
  • Такой подход будет очень запутанным при работе с 10 полями. 21.08.2012
  • Вы правы, я этого не читал. Мое решение просто не было бы полезно для 10 полей. -1 для себя. 21.08.2012
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..