如何一起使用MaskFormatter和DocumentFilter

时间:2014-05-12 19:07:20

标签: java swing jtextfield documentfilter

我需要JFormattedTextField只允许输入##-###**,其中连字符始终出现在文本字段中,最后2个字符由*表示,要么是2个字母的字母(az / AZ),要么根本没有。

我知道如何解决部分问题,但不确定如何将所有内容整合在一起。我知道使用MaskFormatter ##-###**会给我一直存在的连字符,但是我没有办法强制执行最后2个字符的规则,无论是字母还是什么都没有。此外,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();
    }
}

我看到使用它的问题是我无法在文本字段中始终显示连字符。

有人可以帮助我完成这两个所需功能之间的桥梁吗?

1 个答案:

答案 0 :(得分:3)

  

“我无法强制执行最后2个字符的规则,无论是字母还是数字。”

抱歉,您没有看到使用MaskFormatter。如果查看API docs,您会看到可能的字符格式图表

  • #任何有效的数字,使用Character.isDigit。
  • '转义字符,用于转义任何特殊格式字符。
  • U任何字符(Character.isLetter)。所有小写​​字母都映射为大写字母。
  • L任何字符(Character.isLetter)。所有大写字母都映射为小写字母。
  • A任何字符或数字(Character.isLetter或Character.isDigit)
  • ?任何角色(Character.isLetter)。
  • *任何事情。
  • H任何十六进制字符(0-9,a-f或A-F)。

所以你实际上只能使用"##-####UU"


使用InputVerifier

编辑

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