/* SpinnerNumberEditor.java created 2007-10-04
*
*/
package org.signalml.app.view.common.components.spinners;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import javax.swing.JFormattedTextField;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;
import org.signalml.app.model.components.BoundedSpinnerModel;
/**
* Editor of numbers in the spinner, which has
* <ul>
* <li>the decimal format with custom or default pattern,</li>
* <li>the width created based on the bounds of the spinner.</li>
* </ul>
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class SpinnerNumberEditor extends JSpinner.DefaultEditor {
private static final long serialVersionUID = 1L;
/**
* Returns the pattern used to create {@link DecimalFormat}:
* "#,##0.###;-#,##0.###".
* The format is independent from the Locale.
* @param locale the locale
* @return the pattern used to create DecimalFormat
*/
private static String getDefaultPattern(Locale locale) {
// XXX this causes problems and is ugly
/*
ResourceBundle rb = LocaleData.getNumberFormatData(locale);
String[] all = rb.getStringArray("NumberPatterns");
return all[0];
*/
return "#,##0.###;-#,##0.###";
}
/**
* Constructor.
* Sets the DefaultFormatterFactory created based on {@link
* NumberEditorFormatter} in the text field.
* Uses the {@link #getDefaultPattern(Locale) default pattern}.
* @param spinner the spinner for which this editor is to be used
*/
public SpinnerNumberEditor(JSpinner spinner) {
this(spinner, getDefaultPattern(spinner.getLocale()));
}
/**
* Constructor.
* Sets the DefaultFormatterFactory created based on {@link
* NumberEditorFormatter} in the text field.
* @param spinner the spinner for which this is used
* @param defaultPattern the pattern used to created the format of the
* numbers shown in the spinner
*/
public SpinnerNumberEditor(JSpinner spinner, String defaultPattern) {
this(spinner, new DecimalFormat(defaultPattern));
}
/**
* Constructor.
* Sets the DefaultFormatterFactory created based on {@link
* NumberEditorFormatter} in the text field.
* @param spinner the spinner for which this editor is used
* @param format the format of the numbers shown in the spinner
*/
public SpinnerNumberEditor(JSpinner spinner, DecimalFormat format) {
super(spinner);
if (!(spinner.getModel() instanceof BoundedSpinnerModel)) {
throw new IllegalArgumentException(
"model not a BoundedSpinnerModel");
}
BoundedSpinnerModel model = (BoundedSpinnerModel) spinner.getModel();
NumberFormatter formatter = new NumberEditorFormatter(model, format);
DefaultFormatterFactory factory = new DefaultFormatterFactory(formatter);
JFormattedTextField ftf = getTextField();
ftf.setEditable(true);
ftf.setFormatterFactory(factory);
ftf.setHorizontalAlignment(JTextField.RIGHT);
try {
String maxString = formatter.valueToString(model.getMinimum());
String minString = formatter.valueToString(model.getMaximum());
ftf.setColumns(Math.max(maxString.length(),minString.length()));
} catch (ParseException e) {
}
}
/**
* Number formatter with two parameters:
* <ul>
* <li>the format of numbers,</li>
* <li>the {@link BoundedSpinnerModel bounded model}, which is used to
* obtain limits - maximum and minimum.</li></ul>
*
*/
private static class NumberEditorFormatter extends NumberFormatter {
private static final long serialVersionUID = 1L;
/**
* the {@link BoundedSpinnerModel model} for the spinner
*/
private final BoundedSpinnerModel model;
/**
* Constructor. Sets the format of numbers and the model from which
* limits (minimum and maximum) are taken.
* @param model the model
* @param format the format of numbers
*/
NumberEditorFormatter(BoundedSpinnerModel model, NumberFormat format) {
super(format);
this.model = model;
setValueClass(model.getValue().getClass());
}
@Override
public Comparable<? extends Number> getMinimum() {
return model.getMinimum();
}
@Override
public Comparable<? extends Number> getMaximum() {
return model.getMaximum();
}
}
}