Robiłem coś takiego:
import javax.swing.text.*;
public class NumericDocument extends PlainDocument {
private int decimalPrecision;
public NumericDocument(int decimalPrecision) {
super();
this.decimalPrecision = decimalPrecision;
}
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
if (str != null){
if (str.equals(",")) {
str = ".";
}
if (!this.isNumeric(str) && !str.equals(".")) {
return;
} else if (str.equals(".") && super.getText(0, super.getLength()).contains(".")) {
return;
} else if (this.isNumeric(str) && super.getText(0, super.getLength()).indexOf(".") != -1 && offset > super.getText(0, super.getLength()).indexOf(".") && super.getLength() - super.getText(0, super.getLength()).indexOf(".") > decimalPrecision && decimalPrecision > 0) {
return;
}
super.insertString(offset, str, attr);
}
return;
}
private boolean isNumeric(String s) {
return s.matches("\\d*\\.?\\d+");
}
}
Znaki są ograniczone do cyfr i kropki. W konstruktorze przekazujesz ilość cyfr po przecinku jaką może wprowadzić użytkownik. Dodatkowo przecinki są automatycznie zamieniane na kropkę. Pisałem to dosyć dawno, więc może być brzydko (ale nie musi), ale na pewno zrozumiesz. Plusem jest, że wprowadzanych znaków nie widać w polu tekstowym, bo są one odrzucane wcześniej.
Zmodyfikujesz do swoich potrzeb (przecinek zamiast kropki) bez problemu.
Po utworzeniu JTextFielda daj:
textField.setDocument(new NumericDocument(4));