Java 文本字段上的无限聚焦循环

Java 文本字段上的无限聚焦循环,java,swing,focus,infinite-loop,error-checking,Java,Swing,Focus,Infinite Loop,Error Checking,我有两个jtext字段: JTextField txtJobType, txtPriorityCode; 这是我需要的功能: 当用户在txtJobType的“administration”中键入并点击tab或单击“离开”时,将执行错误检查,以查看字段是否为空或输入的文本是否存在于数据库中。我的做法是: private void txtJobTypeFocusLost(java.awt.event.FocusEvent evt) {

我有两个jtext字段:

JTextField txtJobType, txtPriorityCode;
这是我需要的功能:

当用户在txtJobType的“administration”中键入并点击tab或单击“离开”时,将执行错误检查,以查看字段是否为空或输入的文本是否存在于数据库中。我的做法是:

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和Tab设置为Priority,则代码会尝试将焦点返回到jobType,但由于Priority在此时也是空的,因此它会尝试从jobType返回焦点,从而产生以下输出:

PriorityCode Focus Lost
JobType Focus Lost
PriorityCode Focus Lost
JobType Focus Lost
非常感谢您对我如何实现此行为的任何帮助,因为我必须为至少10个其他文本字段执行此操作

谢谢大家!

可以检查一下:

txtPriorityCode.getText().isEmpty()
另一方面,测试是否:

!txtPriorityCode.getText().isEmpty() && txtJobType.getText().isEmpty()
i、 e.只有在第一个不是空的情况下,才对第二个进行检查。

可能对以下各项进行一次检查:

txtPriorityCode.getText().isEmpty()
另一方面,测试是否:

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

i、 e.只有在第一个字段不是空的情况下,才对第二个字段进行检查。

就我个人而言,我讨厌这样做验证,并阻止我以我认为合适的形式在字段中移动。为什么不在提交表单时对所有字段进行验证,并在此时突出显示无效字段?

就我个人而言,我讨厌这样做验证,并阻止我在表单中随意移动字段。为什么不在提交表单时对所有字段进行验证,并在此时突出显示无效字段?

您不应该摆弄焦点丢失或其他低级构造。相反,为什么不按照和使用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;
      }
   }
}

你不应该摆弄焦点丢失或其他低级构造。相反,为什么不按照和使用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;
      }
   }
}


当处理10个字段时,这种方法会变得非常混乱。你是对的,我没有读过。我的解决方案对10个字段没有用处-1我自己。这种方法在处理10个字段时会变得非常混乱。你说得对,我没有读过。我的解决方案对10个字段没有用处-对于我自己,不要像FocusListener那样低级,而是使用InputVerifier@kleo:对不起,我一定是在你输入评论时输入了我的答案。我想伟人的想法是一样的。不要像专注的聆听者那样低级,而是使用InputVerifier@kleo:对不起,我一定是在你输入评论时输入了我的答案。我想伟人也是这样想的。我已经有一段时间没有使用swing了,但是有没有可能使用focusLost方法在内部检查哪个字段失去焦点,并在验证失败时将焦点返回到该字段?我已经有一段时间没有使用swing了,但是有没有可能有一个focusLost方法可以在内部检查哪个字段失去焦点,并在验证失败时将焦点返回到该字段?@kleo:我们一定是同时输入的。这很好,正是我所需要的,除了一件事:我如何实现检查以查看输入的文本是否存在于数据库中?每个textfield都与不同的实体相关联,因此在我的focusLost方法中,您可以看到我传递实体类和表名。我不太明白如何在MyInputVerifier if语句中实现它。@MetalWing:我不认为这是个问题。您可以在验证器的构造函数中传递相同的信息,或者使用哈希映射来保存此信息。@HovercraftFullOfEels听起来很愚蠢,您有机会向我演示这个概念吗?我可以看到公共布尔验证组件输入{在这里我将公开布尔verifyJComponent输入、String tableField、Class entityClass,但如何为构造函数中的每个textfield传递不同的类?@Metal:但请注意,将类类型传递到方法参数会给代码带来不好的味道。我怀疑如果改用泛型,代码会更干净。@kleo:我们必须同时输入。这很好,并且正是我所需要的,除了一件事:我如何执行检查以查看输入的文本是否存在于数据库中?每个文本字段都与不同的实体相关联,因此在我的focusLost方法中,您可以看到我传递实体类和表名。我不太明白如何在MyInputVerifier if语句中实现它。@MetalWing:我不认为这是个问题。你可以在验证器的构造函数中传递相同的信息,或者使用哈希映射来保存这些信息。@HovercraftFullOfEels听起来很愚蠢,你有机会吗
给我演示一下这个概念?我可以看到公共布尔验证组件输入{在这里我将公开布尔verifyJComponent输入、String tableField、Class entityClass,但如何为构造函数中的每个textfield传递不同的类?@Metal:但请注意,将类类型传递到方法参数会给代码带来一种不好的味道。我怀疑如果改用泛型,代码会更干净。