Domanda

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?>

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);
  }
}
È stato utile?

Soluzione

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. (I'm curious why, say, 0.5 isn't legal for you, but that's a separate question.)

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.

When you initially construct the JFormattedTextField you never try to match it on its initial empty value, so it's allowed then. 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; to if (string == null || string.trim().equals("")) return null;... this would allow a blank field.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top