/** * */ package icy.gui.component.editor; import icy.gui.component.SpecialValueSpinner; import icy.gui.component.model.SpecialValueSpinnerModel; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import javax.swing.JFormattedTextField; import javax.swing.JSpinner.DefaultEditor; import javax.swing.SwingConstants; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.NumberFormatter; /** * @author Stephane */ public class SpecialValueSpinnerEditor extends DefaultEditor { /** * */ private static final long serialVersionUID = -2378027484728815432L; private static class NumberEditorFormatter extends NumberFormatter { /** * */ private static final long serialVersionUID = 723313251195326099L; private final SpecialValueSpinnerModel model; NumberEditorFormatter(SpecialValueSpinnerModel model, NumberFormat format) { super(format); this.model = model; setValueClass(model.getValue().getClass()); } @Override public void setMinimum(Comparable min) { model.setMinimum(min); } @Override public Comparable getMinimum() { return model.getMinimum(); } @Override public void setMaximum(Comparable max) { model.setMaximum(max); } @Override public Comparable getMaximum() { return model.getMaximum(); } @Override public Object stringToValue(String text) throws ParseException { if ((text != null) && text.equalsIgnoreCase(model.getSpecialText())) return model.getSpecialValue(); return super.stringToValue(text); } @Override public String valueToString(Object value) throws ParseException { if ((value != null) && value.equals(model.getSpecialValue())) return model.getSpecialText(); return super.valueToString(value); } } public SpecialValueSpinnerEditor(SpecialValueSpinner spinner) { this(spinner, (DecimalFormat) NumberFormat.getInstance(spinner.getLocale())); } public SpecialValueSpinnerEditor(SpecialValueSpinner spinner, String decimalFormatPattern) { this(spinner, new DecimalFormat(decimalFormatPattern)); } private SpecialValueSpinnerEditor(SpecialValueSpinner spinner, DecimalFormat format) { super(spinner); if (!(spinner.getModel() instanceof SpecialValueSpinnerModel)) throw new IllegalArgumentException("model not a SpecialValueSpinnerModel"); SpecialValueSpinnerModel model = (SpecialValueSpinnerModel) spinner.getModel(); NumberFormatter formatter = new NumberEditorFormatter(model, format); DefaultFormatterFactory factory = new DefaultFormatterFactory(formatter); JFormattedTextField ftf = getTextField(); ftf.setEditable(true); ftf.setFormatterFactory(factory); ftf.setHorizontalAlignment(SwingConstants.RIGHT); /* * TBD - initializing the column width of the text field * is imprecise and doing it here is tricky because * the developer may configure the formatter later. */ try { String maxString = formatter.valueToString(model.getMinimum()); String minString = formatter.valueToString(model.getMaximum()); ftf.setColumns(Math.max(maxString.length(), minString.length())); } catch (ParseException e) { // TBD should throw a chained error here } } public DecimalFormat getFormat() { return (DecimalFormat) ((NumberFormatter) (getTextField().getFormatter())).getFormat(); } public SpecialValueSpinnerModel getModel() { return (SpecialValueSpinnerModel) (getSpinner().getModel()); } }