The goal is to have a JSpinner like this with:
SpinnerNumberModel(1650, 1650, 2100, 10);
setEditable(true);
setFocusable(true);
It should also only accept numeric values in the range 1650-2100. If the value is not in this range, set the default value (1650). At the moment, my code only allows me to enter 4 digits, but they are out of range.I have read a lot of similar questions, but I have not found a topic anywhere with a limitation of the input number in the Jspinner.
public class MySpinner extends JSpinner {
int defValue;
int minimum;
int maximum;
int stepSize;
public MySpinner(int defValue, int minimum, int maximum, int stepSize) {
this.defValue = defValue; //1650
this.minimum = minimum; //1650
this.maximum = maximum; //2100
this.stepSize = stepSize; //10
SpinnerNumberModel spinnerNumberModel = new SpinnerNumberModel(defValue, minimum, maximum, stepSize);
setModel(spinnerNumberModel);
setBorder(new EmptyBorder(0, 0, 0, 0));
JSpinner.NumberEditor numberEditor = ((JSpinner.NumberEditor) this.getEditor());
numberEditor.getTextField().setEnabled(true);
numberEditor.getTextField().setEditable(true);
numberEditor.getFormat().setMaximumFractionDigits(4);
JFormattedTextField textField = numberEditor.getTextField();
((NumberFormatter) textField.getFormatter()).setAllowsInvalid(false);
NumberFormatter formatter = (NumberFormatter) textField.getFormatter();
DecimalFormat decimalFormat = new DecimalFormat("0");
formatter.setFormat(decimalFormat);
final Document jsDoc = numberEditor.getTextField().getDocument();
if (jsDoc instanceof PlainDocument) {
AbstractDocument doc = new PlainDocument() {
private static final long serialVersionUID = 1L;
@Override
public void setDocumentFilter(DocumentFilter filter) {
if (filter instanceof MyDocumentFilter) {
super.setDocumentFilter(filter);
}
}
};
doc.setDocumentFilter(new MyDocumentFilter());
numberEditor.getTextField().setDocument(doc);
}
}
public static class MyDocumentFilter extends DocumentFilter {
@Override
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if (stringContainsOnlyDigits(string)) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
super.remove(fb, offset, length);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
int currentLength = fb.getDocument().getLength();
int overLimit = (currentLength + text.length()) - 4 - length;
if (overLimit > 0) {
text = text.substring(0, text.length() - overLimit);
}
if (stringContainsOnlyDigits(text)) {
super.replace(fb, offset, length, text, attrs);
}
}
private boolean stringContainsOnlyDigits(String text) {
for (int i = 0; i < text.length(); i++) {
if (!Character.isDigit(text.charAt(i))) {
return false;
}
}
return true;
}
}
}
Perhaps there is a lot of unnecessary stuff in my code. I would be glad to any advice. Thanks in advance.