Java 如何同时使用MaskFormatter和DocumentFilter
我需要一个Java 如何同时使用MaskFormatter和DocumentFilter,java,swing,jtextfield,documentfilter,Java,Swing,Jtextfield,Documentfilter,我需要一个JFormattedTextField,它只允许输入###-#####***,其中连字符总是出现在文本字段中,最后两个字符(由*表示)可以是字母表中的两个字母(a-z/a-z)或根本没有 我知道如何解决部分问题,但不确定如何将所有问题结合起来。我知道使用#######***的MaskFormatter将为我提供始终存在的连字符,但我无法强制执行最后两个字符要么是字母,要么什么都不是的规则。此外,MaskFormatter将用不需要的最后一个有效插入替换任何删除 我还知道我可以使用Doc
JFormattedTextField
,它只允许输入###-#####***
,其中连字符总是出现在文本字段中,最后两个字符(由*
表示)可以是字母表中的两个字母(a-z/a-z)或根本没有
我知道如何解决部分问题,但不确定如何将所有问题结合起来。我知道使用#######***
的MaskFormatter
将为我提供始终存在的连字符,但我无法强制执行最后两个字符要么是字母,要么什么都不是的规则。此外,MaskFormatter
将用不需要的最后一个有效插入替换任何删除
我还知道我可以使用DocumentFilter
通过使用正则表达式只允许我想要的格式,类似于此功能,但使用不同的正则表达式:
public void insertString(FilterBypass fb, int offs, int length, String str, AttributeSet a)
throws BadLocationException {
String text = fb.getDocument().getText(0, fb.getDocument().getLength());
text += str;
if ((fb.getDocument().getLength() + str.length()
- length) <= maxCharacters && text.matches("^[0-9]+[.]?[0-9]{0,1}$")) {
super.replace(fb, offs, length, str, a);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
public void insertString(FilterBypass fb,int offs,int length,String str,AttributeSet a)
抛出BadLocationException{
字符串text=fb.getDocument().getText(0,fb.getDocument().getLength());
text+=str;
如果((fb.getDocument().getLength()+str.length())
-长度)
“我无法强制执行最后两个字符为字母或数字的规则。”
抱歉,没有看到您使用的是MaskFormatter
。如果查看,您将看到可能的字符格式图表
#
任何有效数字都使用Character.isDigit
”
转义字符,用于转义任何特殊格式字符
U
任何字符(character.isleter)。所有小写字母都映射为大写
L
任何字符(character.isleter)。所有大写字母都映射为小写
A
任何字符或数字(character.isliter或character.isDigit)
?
任何字符(character.isleter)
*
任何东西
H
任何十六进制字符(0-9、a-f或a-f)
所以你可以用“##-#####UU”
使用输入验证程序编辑
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TestMaskFormatter {
private static final String REGEX = "^\\d{2}\\-\\d{4}([A-Z]{2})??";
private static InputVerifier getInputVerifier() {
InputVerifier verifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
JTextField field = (JTextField) input;
String text = field.getText();
return text.matches(REGEX) || text.isEmpty();
}
@Override
public boolean shouldYieldFocus(JComponent input) {
boolean valid = verify(input);
if (!valid) {
JOptionPane.showMessageDialog(null, "Must Match format: 00-0000AA");
JTextField field = (JTextField) input;
field.setText("");
}
return valid;
}
};
return verifier;
}
public static void main(String[] args) {
JTextField fieldWithVerifier = new JTextField(10);
fieldWithVerifier.setInputVerifier(getInputVerifier());
JTextField field1 = new JTextField(10);
JPanel panel = new JPanel();
panel.add(fieldWithVerifier);
panel.add(field1);
JOptionPane.showMessageDialog(null, panel);
}
}
“可以是字母表中的两个字母(a-z/a-z),也可以什么都没有。”这一要求将使匹配正则表达式变得不可能。如果没有一个字母,就不能有两个字母:-(我可能会考虑只进行焦点验证,而不是尝试进行实时验证。如果输入无效,你可以使用InputVerifier
显示错误消息,你确定吗?我对正则表达式不是最擅长的,但我记得读到有量词允许“零次或多次”。你说“你不能有两个字母而不先有一个”,我想知道我的问题是否有误导性。在最后两个条目之前总会有一些东西,但它们都是数字。示例有效输入应该是“12-345”或“12-345AB”"您可以匹配它,但请记住,正如在您的另一个问题中所讨论的,输入是按字母输入的,因此过滤是按字母进行的。因此,如果不首先允许键入0A
,您就不能键入它。但它不能键入,因为您想要的正则表达式与它不匹配。您明白我说的吗?您说的是y你想要0或2个字母。但是如果没有1,就不可能有2个字母。如果用户在第一个字母后停止键入怎么办?我想大多数情况下都是这样。但是,将输入的每个字符添加到筛选器中的字符串中不是就解决了这个问题吗?很抱歉,我不理解,直到上个星期我才接触过此类材料k、 我还想知道如果我使用InputVerifier
路径,我将如何实现与我所需的特定模式匹配的所需功能?感谢您的时间和努力btwSay您键入00-0000
没问题。但是您键入的下一个字符将通过过滤器。如果您键入A
,则不会是be允许,因为你想要的正则表达式只会匹配,比如说00-0000
或00-0000AA
。所以根本没有办法输入00-0000AA
。这就是我的意思。哦,胡说八道,看起来我在第二段中犯了一个与第一段相反的错误。我的意思是说“最后2个字符要么是字母,要么什么都不是"抱歉,我编辑了它。这就是为什么MaksFormter对我来说是个问题。请查看我使用InputVerifer
进行的编辑,您可以键入任何内容,但一旦字段失去焦点,它将被验证,并会弹出一条消息,说明格式错误感谢您的编辑,我尝试过并尝试过使用它,但我仍然无法获得我需要的内容。您的答案显示了如何验证输入,但我需要连字符始终显示为##-#####***
的掩码格式。如果我为带掩码的JFormattedTextField更改fieldWithVerifier
,则无法正确使用验证程序