简体   繁体   English

使用Regex的MaskFormatter

[英]MaskFormatter with Regex

I'm trying to make a textfield that is set to accept floats and I am using regex for this.. I'm having a problem because when I input the number for example 12345.67 then when I try to erase the input I cant erase the number 1.. why?> 我正在尝试使文本字段设置为接受浮点数,并且为此使用了正则表达式。我遇到了问题,因为当我输入数字(例如12345.67)时,然后当我尝试擦除输入时,无法擦除数字1 ..为什么?

import javax.swing.*;
import javax.swing.text.*;

public class DecimalFormatter extends DefaultFormatter {

  protected java.util.regex.Matcher matcher;

  public DecimalFormatter(java.util.regex.Pattern regex) {
    setOverwriteMode(false);
    matcher = regex.matcher("");
  }

  public Object stringToValue(String string) throws java.text.ParseException {
    if (string == null) return null;
    matcher.reset(string);

    if (! matcher.matches())
      throw new java.text.ParseException("does not match regex", 0);

    return super.stringToValue(string);
  }


  public static void main(String argv[]) {

    JLabel lab1 = new JLabel("Decimal:");
    java.util.regex.Pattern Decimal = java.util.regex.Pattern.compile("^[1-9]\\d{0,4}([.]\\d{0,2})?$",  java.util.regex.Pattern.CASE_INSENSITIVE);
    DecimalFormatter decimalFormatter = new DecimalFormatter(Decimal);
    decimalFormatter.setAllowsInvalid(false);
    JFormattedTextField ftf1 = new JFormattedTextField(decimalFormatter);

    JFrame f = new JFrame("DecimalFormatter Demo");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel pan1 = new JPanel(new java.awt.BorderLayout());
    pan1.add(lab1, java.awt.BorderLayout.WEST);
    pan1.add(ftf1, java.awt.BorderLayout.CENTER);
    lab1.setLabelFor(ftf1);
    f.getContentPane().add(pan1, java.awt.BorderLayout.SOUTH);
    f.setSize(300, 80);
    f.setVisible(true);
  }
}

Because your regular expression doesn't allow for it. 因为您的正则表达式不允许这样做。 Your regular expression matches Strings that start with a digit 1-9, followed by up to four more digits, then optionally a period and up to two more digits. 您的正则表达式匹配以1-9开头的字符串,然后是最多四个数字,然后是句点和最多两个数字。 (I'm curious why, say, 0.5 isn't legal for you, but that's a separate question.) (我很好奇为什么说0.5对您不合法,但这是一个单独的问题。)

The empty string (what you have after deleting the 1 in your example) doesn't match this regex, and so the JFormattedTextField won't allow it. 空字符串(在示例中删除1后的内容)与此正则表达式不匹配,因此JFormattedTextField不允许使用它。

When you initially construct the JFormattedTextField you never try to match it on its initial empty value, so it's allowed then. 最初构造JFormattedTextField您永远不要尝试将其与初始空值匹配,因此允许它。 But when the user starts typing, you run the match on all the values subsequently entered, including (if applicable) the empty string when all characters are deleted. 但是,当用户开始键入内容时,您将对随后输入的所有值(包括(如果适用)包括删除所有字符时的空字符串)进行匹配。

You could try changing if (string == null) return null; 您可以尝试更改if (string == null) return null; to if (string == null || string.trim().equals("")) return null; if (string == null || string.trim().equals("")) return null; ... this would allow a blank field. ...这将允许一个空白字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM