问题
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