I am newbie to Java programming. I have a document filter that only allow numeric values and decimals with "." in a JFormattedTextField
. Now I want to implement a method within that filter, to only allow a maximum and minimum value , like I want whatever the value of number entered, it must be between [0-1], otherwise it should not accept whatever is typed.
Now I don't want to use JSpinner
, because from 0 to 1 there is millions of Decimals eg: 0.0001, 0.0012 ...
This is my documentFilter
code:
package javagui.views;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;
public class SeulementNumerique extends PlainDocument {
public static final String FLOAT = "0123456789.";
protected String acceptedChars = null;
protected boolean negativeAccepted = false;
public SeulementNumerique() {
this(FLOAT);
}
public SeulementNumerique(String acceptedchars) {
acceptedChars = acceptedchars;
}
public void setNegativeAccepted(boolean negativeaccepted) {
if (acceptedChars.equals(FLOAT)) {
negativeAccepted = negativeaccepted;
acceptedChars += "-";
}
}
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
if (str == null)
return;
for (int i = 0; i < str.length(); i++) {
if (acceptedChars.indexOf(str.valueOf(str.charAt(i))) == -1)
return;
}
if (acceptedChars.equals(FLOAT) || (acceptedChars.equals(FLOAT + "-") && negativeAccepted)) {
if (str.indexOf(".") != -1) {
if (getText(0, getLength()).indexOf(".") != -1) {
return;
}
}
}
if (negativeAccepted && str.indexOf("-") != -1) {
if (str.indexOf("-") != 0 || offset != 0) {
return;
}
}
super.insertString(offset, str, attr);
}
}
Now to call for that Filter in my main code I use:
formattedTextField_5 = new JFormattedTextField();
formattedTextField_5.setDocument(new SeulementNumerique());
Is there any simple way to set Maximum and Minimum value that can be entered in a JFormattedTextField?
A JTextField can be used with a custom DocumentFilter that checks values are numeric and within the specified range. Below is a sample DocumentFilter that accomplishes just that:
public class RestrictedNumberDocumentFilter extends DocumentFilter{
private double min;
private double max;
public RestrictedNumberDocumentFilter(double min, double max){
if ( max < min ){
double temp = max;
max = min;
min = temp;
}
this.min = min;
this.max = max;
}
@Override
public void insertString(FilterBypass fb, int off, String str, AttributeSet attr) throws BadLocationException {
StringBuilder sb = new StringBuilder(fb.getDocument().getText(0, fb.getDocument().getLength()));
if ( test(sb.toString()) ){
fb.insertString(off, str, attr);
}else{
//warn
}
}
@Override
public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)throws BadLocationException{
StringBuilder sb = new StringBuilder(fb.getDocument().getText(0, fb.getDocument().getLength()));
sb.replace(off, off+len, str);
if ( test(sb.toString()) ){
fb.replace(off, len, str, attr);
}else{
//warn
}
}
/**
* Sanitized the input
* @param val
* @return
*/
private boolean test(String val){
try{
double d = Double.parseDouble(val);
if ( d >= min && d <= max ){
return true;
}
return false;
}catch(NumberFormatException e){
return false;
}
}
}
To use this class, set the DocumentFilter for the Document of the JTextField
JTextField field = new JTextField();
AbstractDocument doc = (AbstractDocument )field.getDocument();
doc.setDocumentFilter(new RestrictedNumberDocumentFilter (min, max));
You might need to customize this class further for whatever input you anticipate.
You can do a similar thing with a JFormattedTextField, but it may have its own issues with using a custom DocumentFilter as described here