问题
I want to perform data validation while JOptionPane.I found the following approach but i am not really satisfied with it
import javax.swing.*;
import java.util.regex.*;
public class ValidateJOptionPane {
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("Enter number: ");
Pattern p = Pattern.compile("[A-Z,a-z,&%$#@!()*^]");
Matcher m = p.matcher(input);
if (m.find()) {
JOptionPane.showMessageDialog(null, "Please enter only numbers");
}
}
}
It would have been better and more sensible to use the regex to detect the characters that can be entered rather than testing for characters that can't be entered.
Is there a better and simpler way to do data validation with JOptionPane ? . I feel regex is overkill here.Correct me if i am wrong:P
P.S i am a beginner with Java
回答1:
The long answer is, use DocumentFilter
, see Implementing a Document Filter and DocumentFilter Examples for more details.
The problem with this is, you need to take control, you can't rely on the "simple", "helper" functionality provided by JOptionPane.showInputDialog
, as you need access to the text field been used to prompt the user...
For example...
The following examples uses a (slightly) modified version of the PatternFilter
from DocumentFilter Examples
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class ValidateTest {
public static void main(String[] args) {
JTextField field = new JTextField(20);
Pattern p = Pattern.compile("[0-9]+");
((AbstractDocument) field.getDocument()).setDocumentFilter(new PatternFilter(p));
int option = ask("Enter number:", field);
if (option == JOptionPane.OK_OPTION) {
System.out.println("You have entered " + field.getText());
}
}
public static int ask(String label, JComponent comp) {
JPanel panel = new JPanel();
panel.add(new JLabel(label));
panel.add(comp);
return JOptionPane.showOptionDialog(null, panel, label,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
}
public static class PatternFilter extends DocumentFilter {
// Useful for every kind of input validation !
// this is the insert pattern
// The pattern must contain all subpatterns so we can enter characters into a text component !
private Pattern pattern;
public PatternFilter(Pattern p) {
pattern = p;
}
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
throws BadLocationException {
String newStr = fb.getDocument().getText(0, fb.getDocument().getLength()) + string;
Matcher m = pattern.matcher(newStr);
if (m.matches()) {
super.insertString(fb, offset, string, attr);
} else {
}
}
public void replace(FilterBypass fb, int offset,
int length, String string, AttributeSet attr) throws
BadLocationException {
if (length > 0) {
fb.remove(offset, length);
}
insertString(fb, offset, string, attr);
}
}
}
Now, with a little clever design, you could write a simple helper class which built all this internally and provided a nice askFor(String label, Pattern p)
style method that could return a String
(or null
if the user canceled the operation)
回答2:
As you said "It would have been better and more sensible to use the regex to detect the characters that can be entered rather than testing for characters that can't be entered." So you can just do the reverse checking then :
import javax.swing.*;
import java.util.regex.*;
public class ValidateJOptionPane {
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("Enter number: ");
Pattern p = Pattern.compile("^[0-9]*$");
Matcher m = p.matcher(input);
if (!m.find()) { // if pattern doesn't match (not found)
JOptionPane.showMessageDialog(null, "Please enter only numbers");
}
}
}
[0-9]
means digit 0-9 while *
means some spaces
来源:https://stackoverflow.com/questions/25418243/data-validation-with-joptionpane