Infinite focus loop on textFields

一世执手 提交于 2019-12-11 05:19:15

问题


I have 2 JTextFields:

JTextField txtJobType, txtPriorityCode;

This is the functionality I need:

When user types in 'administration' in txtJobType and hits tab (or clicks away) an error check is done to see whether the field is empty or if the text entered exists in database. The way I have done that is:

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 {
    }
} 

So if the field doesn't exist or the text is empty, then return focus to the txtJobType and highlight all the text (if any)

That works without a problem. However, I have the txtPriorityCode field which needs to have the exact same behaviour. So I did:

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

This is where the problem starts: if user leaves jobType and tabs to Priority then the code attempts to return focus back to jobtype, but because priority is also blank at that point, it will attempt to get focus back from jobtype, resulting in this output:

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

Any help on how I could implement this behaviour is appreciated, as I have to do this for at least 10 other textfields.

Thank You!


回答1:


You shouldn't be fiddling with focus lost or other low-level constructs. Instead, why not simply use an InputVerifier as per this example and this one too?

For example, it could look something like this:

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



回答2:


Personally, I hate it when validation is done like this and prevents me from moving around fields in a form as I see fit. Why not do validation on all the fields when the form is submitted and highlight the invalid ones at that time?




回答3:


Maybe do one check of:

txtPriorityCode.getText().isEmpty()

And then on the other, test if:

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

i.e. only do the check on the second one if the first one isn't empty.



来源:https://stackoverflow.com/questions/12058212/infinite-focus-loop-on-textfields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!