- Megjelent: 2012. augusztus 18
A JSpinner, pontosbban a JSpinner modellek komoly fogyatékossága, hogy nem képesek kezelni a null értékeket és az üres értéket. Az egyik lehetőség, hogy a fejlesztő megírja a saját modelljét vagy származtat a megévő modellekből, ami nem egy hálás feladat, netán keres az Interneten (én nem találtam).
De van egy egyszerű megoldás a problémára: közvetlenül a JSpinner editor szöveges mezőjét is lehet használni a null érték tárolására: ha null-t állítunk be, üres String-re álíltjuk, lekérdezésnél pedig megvizsgáljuk, hogy üres String-e az értéke, és ha igen, akkor az null értéket jelent.
Ehhez két dolog kell:
- Null érték tárolására alkalmas modell
- Üres mező kezelésére alkalmas editor
Null érték tárolására alkalmas modell
public class ExtraSpinnerNumberModel extends SpinnerNumberModel {
private boolean nullValue = false;
public ExtraSpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) {
super(value, minimum, maximum, stepSize);
}
public ExtraSpinnerNumberModel(int value, int minimum, int maximum, int stepSize) {
super(value, minimum, maximum, stepSize);
}
public ExtraSpinnerNumberModel(double value, double minimum, double maximum, double stepSize) {
super(value, minimum, maximum, stepSize);
}
public ExtraSpinnerNumberModel() {
}
@Override
public Object getValue() {
return nullValue ? null : super.getValue();
}
@Override
public void setValue(Object value) {
boolean wasNull = nullValue;
nullValue = value == null;
if (!nullValue) {
super.setValue(value);
} else if (!wasNull) {
fireStateChanged();
}
}
@Override
public Object getNextValue() {
return nullValue ? null : super.getNextValue();
}
@Override
public Object getPreviousValue() {
return nullValue ? null : super.getPreviousValue();
}
}
Üres mező kezelésére alkalmas editor
public class ExtraNumberEditor extends JSpinner.NumberEditor {
public ExtraNumberEditor(JSpinner spinner) {
super(spinner);
NumberEditorFormatter nef = new NumberEditorFormatter();
SpinnerModel model = spinner.getModel();
if (model instanceof SpinnerNumberModel) {
SpinnerNumberModel numberModel = (SpinnerNumberModel) model;
nef.setMinimum(numberModel.getMinimum());
nef.setMaximum(numberModel.getMaximum());
}
getTextField().setFormatterFactory(new DefaultFormatterFactory(nef));
}
public ExtraNumberEditor(JSpinner spinner, String decimalFormatPattern) {
super(spinner);
NumberEditorFormatter nef
= new NumberEditorFormatter(decimalFormatPattern);
SpinnerModel model = spinner.getModel();
if (model instanceof SpinnerNumberModel) {
SpinnerNumberModel numberModel = (SpinnerNumberModel) model;
nef.setMinimum(numberModel.getMinimum());
nef.setMaximum(numberModel.getMaximum());
}
getTextField().setFormatterFactory(new DefaultFormatterFactory(nef));
}
static class NumberEditorFormatter
extends NumberFormatter {
public NumberEditorFormatter() {
super(NumberFormat.getInstance());
}
public NumberEditorFormatter(String decimalFormatPattern) {
super(new DecimalFormat(decimalFormatPattern));
}
@Override
public Object stringToValue(String text) throws ParseException {
if (text.isEmpty()) {
return null;
}
return super.stringToValue(text);
}
@Override
public String valueToString(Object value) throws ParseException {
if (value == null) {
return "";
}
return super.valueToString(value);
}
}
}
Modell és editor beállítása
spinner.setModel(new ExtraSpinnerNumberModel(Double.valueOf(0.0), null, null, Double.valueOf(1.0)));
spinner.setEditor(new ExtraNumberEditor(spinner));