问题
I have a delicate problem!
I have a form that set input verifier to text fields, and when user type a incorrect value, other text fields and radio buttons should be disable.
In second text filed (last name), When user type a incorrect value, other components disable perfectly, But when user edit that value to correct it, (for e.x by removing digit), user should user keyboard tab
button to enable other components (radio buttons) and I want to enable with clicking to radio buttons too.
Here is my code:
public class UserDialog3 extends JDialog implements ActionListener {
JButton cancelBtn, okBtn;
JTextField fNameTf, lNameTf;
JRadioButton maleRb, femaleRb;
ButtonGroup group;
JLabel fNameLbl, lNameLbl, genderLbl, tempBtn, temp3, temp2, temp1;
public UserDialog3() {
add(createForm(), BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocation(400, 100);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new UserDialog3();
}
});
}
public JPanel createForm() {
JPanel panel = new JPanel();
okBtn = new JButton("Ok");
cancelBtn = new JButton("Cancel");
tempBtn = new JLabel();
fNameLbl = new JLabel("First Name");
lNameLbl = new JLabel("Last Name");
genderLbl = new JLabel("Gender");
temp2 = new JLabel();
temp1 = new JLabel();
maleRb = new JRadioButton("Male");
femaleRb = new JRadioButton("Female");
temp3 = new JLabel();
group = new ButtonGroup();
group.add(maleRb);
group.add(femaleRb);
fNameTf = new JTextField(10);
fNameTf.setName("FnTF");
fNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
lNameTf = new JTextField(10);
lNameTf.setName("LnTF");
lNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
panel.add(fNameLbl);
panel.add(fNameTf);
panel.add(temp1);
panel.add(lNameLbl);
panel.add(lNameTf);
panel.add(temp2);
panel.add(genderLbl);
JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
radioPanel.add(maleRb);
radioPanel.add(femaleRb);
panel.add(radioPanel);
panel.add(temp3);
panel.add(okBtn);
panel.add(cancelBtn);
panel.add(tempBtn);
panel.setLayout(new SpringLayout());
SpringUtilities.makeCompactGrid(panel, 4, 3, 50, 10, 80, 60);
return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
}
public class MyVerifier extends InputVerifier {
private JComponent[] component;
public MyVerifier(JComponent[] components) {
component = components;
}
@Override
public boolean verify(JComponent input) {
String name = input.getName();
if (name.equals("FnTF")) {
String text = ((JTextField) input).getText().trim();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
} else if (name.equals("LnTF")) {
String text = ((JTextField) input).getText();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
}
//enable dependent components
for (JComponent r : component) {
r.setEnabled(true);
}
return true;
}
}
}
回答1:
The purpose of InputVerifier
class is to help clients support smooth focus navigation through GUIs with text fields. Before focus is transfered to another Swing component that requests it, the input verifier's shouldYieldFocus
method is called(which ask the verify
function to validate data). Focus is transfered only if that method returns true
.
Please Try to fix the issues about using InutVerifier
, verify
and shouldYieldFunction
as mentioned in your previous post. If you are not going to change your practice, you will be danger in future. Remove you components enabling and disabling code from verify function.
Your Problem in this post: In this case, what really happening is that, when your data is invalid and you try to lose your input text field focus by clicking another component, your JRadioButtons
get disabled. A disabled cant be focused until it is re-enabled. As input-verifier responds with focus-lose event, clicking on the disabled RadioButton
isn't resulting in focus navigation, and thus ShouldYieldFocus(which calls verify)
is not being called to re-enable your components.
Pressing the tab works, because it is sending the Focus to your second text input field according to swing's focus traversal policy. Hence a focus lose event occur on first input text field and this time InputVerifier
's verify function get called which eventually enables your component. To understand the problem better, try rewriting your own example with one JRadioButton
and one JTextFeild
.
Try using a DocumentListener with your text Field. upon data insertion and removal event, check your data validity using InputVerifier
and then, enable/disable related components.
I am writing a sample code snippets to demonstrate, how adding DocumentListener
to your fNameTF
and lNameTF
text fields will resolve your problem:
fNameTF.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
doOnDataValidity(verifier.verify(fNameTF));
}
@Override
public void removeUpdate(DocumentEvent e) {
doOnDataValidity(verifier.verify(fNameTF));
}
@Override
public void changedUpdate(DocumentEvent e) {}
});
doOnValidity(boolean isValid)
function is as follows:
public void doOnDataValidity(boolean isDataValid)
{
if(isDataValid)
{
//enable your components
}else
{
//disable your components
}
}
Add a DocumentListener to your lNameTf.getDocument()
the same way.
Tutorial Resources: How to use DocumentListener.
来源:https://stackoverflow.com/questions/19565839/input-verifier-effect-not-work-by-click-just-work-by-tab-button