在JFormattedTextField中删除掩码时出现问题

And*_*der 5 java swing jformattedtextfield

我在JFormattedTextField中遇到掩码时遇到问题

我知道它用空格替换无效字符,或者用setPlaceholderCharacter定义的任何东西,但我需要它做的是允许删除或退格,并且不插入空格代替我删除的字符,只要其余的掩码中允许使用string.

例如,使用mask : *#*****,字符串"12 abc"有效.
如果你把光标放在b和c字符之间,然后按退格按钮,我需要它来删除b,导致"12 ac".相反,它删除它,并添加一个空格,成为:"12 a c".

下面是一个简单的代码示例来演示.

我很感激任何想法或例子来解决这个问题.


public class testFrame extends javax.swing.JFrame {

    public testFrame() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());

        setMinimumSize(new Dimension(300,150));

        java.awt.Button closeButton = new java.awt.Button();
        JFormattedTextField maskTextField = new JFormattedTextField();
        maskTextField.setMinimumSize(new Dimension(100,30));

        getContentPane().add(maskTextField);

        closeButton.setLabel("close");
        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                System.exit(0);
            }
        });

        getContentPane().add(closeButton);

        try {
            MaskFormatter someMask = new MaskFormatter("*#****");
            DefaultFormatterFactory formatterFactory 
                = new DefaultFormatterFactory(someMask);
            maskTextField.setFormatterFactory(formatterFactory);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        maskTextField.setText("12 abc");

        pack();

    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new testFrame().setVisible(true);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

更新代码以反映以下答案.我添加了第二个字段,以便您可以看到有和没有修复的行为.同样是一个小修复,我调整了窗口的大小并将其置于屏幕中心以使其更加友好.

public class testFrame扩展了javax.swing.JFrame {

public testFrame() {
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setMinimumSize(new java.awt.Dimension(300, 200));
    getContentPane().setLayout(new java.awt.FlowLayout());


    JFormattedTextField maskTextField = new JFormattedTextField();
    maskTextField.setMinimumSize(new Dimension(100,30));
    getContentPane().add(maskTextField);


    JFormattedTextField maskTextField2 = new JFormattedTextField();
    maskTextField2.setMinimumSize(new Dimension(100,30));
    getContentPane().add(maskTextField2);

    java.awt.Button closeButton = new java.awt.Button();
    closeButton.setLabel("close");
    closeButton.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            System.exit(0);
        }
    });

    getContentPane().add(closeButton);

    try {

        MaskFormatter someMask = new MaskFormatter("*#****");
        DefaultFormatterFactory formatterFactory = 
            new DefaultFormatterFactory(someMask);
        maskTextField.setFormatterFactory(formatterFactory);

        MaskFormatter someMask2 = new MaskFormatter("*#****");
        DefaultFormatterFactory formatterFactory2 = 
            new DefaultFormatterFactory(someMask2);
        maskTextField2.setFormatterFactory(formatterFactory2);

    } catch (ParseException ex) {
        ex.printStackTrace();
    }

    maskTextField.setText("12 abc");
    maskTextField2.setText("12 abc");

    // added per suggestion below
    if (maskTextField.getFormatter() instanceof DefaultFormatter) {
         DefaultFormatter f = (DefaultFormatter) maskTextField.getFormatter();
         f.setAllowsInvalid(true);

         // options are: 
         // JFormattedTextField.COMMIT
         // JFormattedTextField.COMMIT_OR_REVERT  --> default
         // JFormattedTextField.REVERT
         // JFormattedTextField.PERSIST
         maskTextField.setFocusLostBehavior(JFormattedTextField.PERSIST);
    } 
    pack();
    this.setLocationRelativeTo(null);

}

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {

        public void run() {
            new testFrame().setVisible(true);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

}

Dun*_*nes 5

首先,感谢您发布一个体面的工作示例.

看来这DefaultFormatter是掩码文本字段使用的格式化程序.我发现我可以通过以下方式允许临时无效编辑:

if (maskTextField.getFormatter() instanceof DefaultFormatter) {
  DefaultFormatter f = (DefaultFormatter) maskTextField.getFormatter();
  f.setAllowsInvalid(true);          
}
Run Code Online (Sandbox Code Playgroud)

希望这足以让你开始.虽然请注意,如果在字段中存在无效值时更改焦点,则此快速修复具有完全擦除文本字段内容的有趣行为.这似乎与JavaDoc相反,JFormattedTextField后者表明默认行为是COMMIT_OR_REVERT.