diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/JSpinner.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/JSpinner.java')
-rw-r--r-- | libjava/classpath/javax/swing/JSpinner.java | 754 |
1 files changed, 754 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JSpinner.java b/libjava/classpath/javax/swing/JSpinner.java new file mode 100644 index 000000000..e942caead --- /dev/null +++ b/libjava/classpath/javax/swing/JSpinner.java @@ -0,0 +1,754 @@ +/* JSpinner.java -- + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.SpinnerUI; +import javax.swing.text.DateFormatter; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; + +/** + * A <code>JSpinner</code> is a component that displays a single value from + * a sequence of values, and provides a convenient means for selecting the + * previous and next values in the sequence. Typically the spinner displays + * a numeric value, but it is possible to display dates or arbitrary items + * from a list. + * + * @author Ka-Hing Cheung + * + * @since 1.4 + */ +public class JSpinner extends JComponent +{ + /** + * The base class for the editor used by the {@link JSpinner} component. + * The editor is in fact a panel containing a {@link JFormattedTextField} + * component. + */ + public static class DefaultEditor + extends JPanel + implements ChangeListener, PropertyChangeListener, LayoutManager + { + /** The spinner that the editor is allocated to. */ + private JSpinner spinner; + + /** The JFormattedTextField that backs the editor. */ + JFormattedTextField ftf; + + /** + * For compatability with Sun's JDK 1.4.2 rev. 5 + */ + private static final long serialVersionUID = -5317788736173368172L; + + /** + * Creates a new <code>DefaultEditor</code> object. The editor is + * registered with the spinner as a {@link ChangeListener} here. + * + * @param spinner the <code>JSpinner</code> associated with this editor + */ + public DefaultEditor(JSpinner spinner) + { + super(); + setLayout(this); + this.spinner = spinner; + ftf = new JFormattedTextField(); + add(ftf); + ftf.setValue(spinner.getValue()); + ftf.addPropertyChangeListener(this); + if (getComponentOrientation().isLeftToRight()) + ftf.setHorizontalAlignment(JTextField.RIGHT); + else + ftf.setHorizontalAlignment(JTextField.LEFT); + spinner.addChangeListener(this); + } + + /** + * Returns the <code>JSpinner</code> component that the editor is assigned + * to. + * + * @return The spinner that the editor is assigned to. + */ + public JSpinner getSpinner() + { + return spinner; + } + + /** + * DOCUMENT ME! + */ + public void commitEdit() throws ParseException + { + // TODO: Implement this properly. + } + + /** + * Removes the editor from the {@link ChangeListener} list maintained by + * the specified <code>spinner</code>. + * + * @param spinner the spinner (<code>null</code> not permitted). + */ + public void dismiss(JSpinner spinner) + { + spinner.removeChangeListener(this); + } + + /** + * Returns the text field used to display and edit the current value in + * the spinner. + * + * @return The text field. + */ + public JFormattedTextField getTextField() + { + return ftf; + } + + /** + * Sets the bounds for the child components in this container. In this + * case, the text field is the only component to be laid out. + * + * @param parent the parent container. + */ + public void layoutContainer(Container parent) + { + Insets insets = getInsets(); + Dimension size = getSize(); + ftf.setBounds(insets.left, insets.top, + size.width - insets.left - insets.right, + size.height - insets.top - insets.bottom); + } + + /** + * Calculates the minimum size for this component. In this case, the + * text field is the only subcomponent, so the return value is the minimum + * size of the text field plus the insets of this component. + * + * @param parent the parent container. + * + * @return The minimum size. + */ + public Dimension minimumLayoutSize(Container parent) + { + Insets insets = getInsets(); + Dimension minSize = ftf.getMinimumSize(); + return new Dimension(minSize.width + insets.left + insets.right, + minSize.height + insets.top + insets.bottom); + } + + /** + * Calculates the preferred size for this component. In this case, the + * text field is the only subcomponent, so the return value is the + * preferred size of the text field plus the insets of this component. + * + * @param parent the parent container. + * + * @return The preferred size. + */ + public Dimension preferredLayoutSize(Container parent) + { + Insets insets = getInsets(); + Dimension prefSize = ftf.getPreferredSize(); + return new Dimension(prefSize.width + insets.left + insets.right, + prefSize.height + insets.top + insets.bottom); + } + + /** + * Receives notification of property changes. If the text field's 'value' + * property changes, the spinner's model is updated accordingly. + * + * @param event the event. + */ + public void propertyChange(PropertyChangeEvent event) + { + if (event.getSource() == ftf) + { + if (event.getPropertyName().equals("value")) + spinner.getModel().setValue(event.getNewValue()); + } + } + + /** + * Receives notification of changes in the state of the {@link JSpinner} + * that the editor belongs to - the content of the text field is updated + * accordingly. + * + * @param event the change event. + */ + public void stateChanged(ChangeEvent event) + { + ftf.setValue(spinner.getValue()); + } + + /** + * This method does nothing. It is required by the {@link LayoutManager} + * interface, but since this component has a single child, there is no + * need to use this method. + * + * @param child the child component to remove. + */ + public void removeLayoutComponent(Component child) + { + // Nothing to do here. + } + + /** + * This method does nothing. It is required by the {@link LayoutManager} + * interface, but since this component has a single child, there is no + * need to use this method. + * + * @param name the name. + * @param child the child component to add. + */ + public void addLayoutComponent(String name, Component child) + { + // Nothing to do here. + } + } + + /** + * A panel containing a {@link JFormattedTextField} that is configured for + * displaying and editing numbers. The panel is used as a subcomponent of + * a {@link JSpinner}. + * + * @see JSpinner#createEditor(SpinnerModel) + */ + public static class NumberEditor extends DefaultEditor + { + /** + * For compatability with Sun's JDK + */ + private static final long serialVersionUID = 3791956183098282942L; + + /** + * Creates a new <code>NumberEditor</code> object for the specified + * <code>spinner</code>. The editor is registered with the spinner as a + * {@link ChangeListener}. + * + * @param spinner the component the editor will be used with. + */ + public NumberEditor(JSpinner spinner) + { + super(spinner); + NumberEditorFormatter nef = new NumberEditorFormatter(); + nef.setMinimum(getModel().getMinimum()); + nef.setMaximum(getModel().getMaximum()); + ftf.setFormatterFactory(new DefaultFormatterFactory(nef)); + } + + /** + * Creates a new <code>NumberEditor</code> object. + * + * @param spinner the spinner. + * @param decimalFormatPattern the number format pattern. + */ + public NumberEditor(JSpinner spinner, String decimalFormatPattern) + { + super(spinner); + NumberEditorFormatter nef + = new NumberEditorFormatter(decimalFormatPattern); + nef.setMinimum(getModel().getMinimum()); + nef.setMaximum(getModel().getMaximum()); + ftf.setFormatterFactory(new DefaultFormatterFactory(nef)); + } + + /** + * Returns the format used by the text field. + * + * @return The format used by the text field. + */ + public DecimalFormat getFormat() + { + NumberFormatter formatter = (NumberFormatter) ftf.getFormatter(); + return (DecimalFormat) formatter.getFormat(); + } + + /** + * Returns the model used by the editor's {@link JSpinner} component, + * cast to a {@link SpinnerNumberModel}. + * + * @return The model. + */ + public SpinnerNumberModel getModel() + { + return (SpinnerNumberModel) getSpinner().getModel(); + } + } + + static class NumberEditorFormatter + extends NumberFormatter + { + public NumberEditorFormatter() + { + super(NumberFormat.getInstance()); + } + public NumberEditorFormatter(String decimalFormatPattern) + { + super(new DecimalFormat(decimalFormatPattern)); + } + } + + /** + * A <code>JSpinner</code> editor used for the {@link SpinnerListModel}. + * This editor uses a <code>JFormattedTextField</code> to edit the values + * of the spinner. + * + * @author Roman Kennke (kennke@aicas.com) + */ + public static class ListEditor extends DefaultEditor + { + /** + * Creates a new instance of <code>ListEditor</code>. + * + * @param spinner the spinner for which this editor is used + */ + public ListEditor(JSpinner spinner) + { + super(spinner); + } + + /** + * Returns the spinner's model cast as a {@link SpinnerListModel}. + * + * @return The spinner's model. + */ + public SpinnerListModel getModel() + { + return (SpinnerListModel) getSpinner().getModel(); + } + } + + /** + * An editor class for a <code>JSpinner</code> that is used + * for displaying and editing dates (e.g. that uses + * <code>SpinnerDateModel</code> as model). + * + * The editor uses a {@link JTextField} with the value + * displayed by a {@link DateFormatter} instance. + */ + public static class DateEditor extends DefaultEditor + { + + /** The serialVersionUID. */ + private static final long serialVersionUID = -4279356973770397815L; + + /** + * Creates a new instance of DateEditor for the specified + * <code>JSpinner</code>. + * + * @param spinner the <code>JSpinner</code> for which to + * create a <code>DateEditor</code> instance + */ + public DateEditor(JSpinner spinner) + { + super(spinner); + DateEditorFormatter nef = new DateEditorFormatter(); + nef.setMinimum(getModel().getStart()); + nef.setMaximum(getModel().getEnd()); + ftf.setFormatterFactory(new DefaultFormatterFactory(nef)); + } + + /** + * Creates a new instance of DateEditor for the specified + * <code>JSpinner</code> using the specified date format + * pattern. + * + * @param spinner the <code>JSpinner</code> for which to + * create a <code>DateEditor</code> instance + * @param dateFormatPattern the date format to use + * + * @see SimpleDateFormat#SimpleDateFormat(String) + */ + public DateEditor(JSpinner spinner, String dateFormatPattern) + { + super(spinner); + DateEditorFormatter nef = new DateEditorFormatter(dateFormatPattern); + nef.setMinimum(getModel().getStart()); + nef.setMaximum(getModel().getEnd()); + ftf.setFormatterFactory(new DefaultFormatterFactory(nef)); + } + + /** + * Returns the <code>SimpleDateFormat</code> instance that is used to + * format the date value. + * + * @return the <code>SimpleDateFormat</code> instance that is used to + * format the date value + */ + public SimpleDateFormat getFormat() + { + DateFormatter formatter = (DateFormatter) ftf.getFormatter(); + return (SimpleDateFormat) formatter.getFormat(); + } + + /** + * Returns the {@link SpinnerDateModel} that is edited by this editor. + * + * @return the <code>SpinnerDateModel</code> that is edited by this editor + */ + public SpinnerDateModel getModel() + { + return (SpinnerDateModel) getSpinner().getModel(); + } + } + + static class DateEditorFormatter + extends DateFormatter + { + public DateEditorFormatter() + { + super(DateFormat.getInstance()); + } + public DateEditorFormatter(String dateFormatPattern) + { + super(new SimpleDateFormat(dateFormatPattern)); + } + } + + /** + * A listener that forwards {@link ChangeEvent} notifications from the model + * to the {@link JSpinner}'s listeners. + */ + class ModelListener implements ChangeListener + { + /** + * Creates a new listener. + */ + public ModelListener() + { + // nothing to do here + } + + /** + * Receives notification from the model that its state has changed. + * + * @param event the event (ignored). + */ + public void stateChanged(ChangeEvent event) + { + fireStateChanged(); + } + } + + /** + * The model that defines the current value and permitted values for the + * spinner. + */ + private SpinnerModel model; + + /** The current editor. */ + private JComponent editor; + + private static final long serialVersionUID = 3412663575706551720L; + + /** + * Creates a new <code>JSpinner</code> with default instance of + * {@link SpinnerNumberModel} (that is, a model with value 0, step size 1, + * and no upper or lower limit). + * + * @see javax.swing.SpinnerNumberModel + */ + public JSpinner() + { + this(new SpinnerNumberModel()); + } + + /** + * Creates a new <code>JSpinner with the specified model. The + * {@link #createEditor(SpinnerModel)} method is used to create an editor + * that is suitable for the model. + * + * @param model the model (<code>null</code> not permitted). + * + * @throws NullPointerException if <code>model</code> is <code>null</code>. + */ + public JSpinner(SpinnerModel model) + { + this.model = model; + this.editor = createEditor(model); + model.addChangeListener(new ModelListener()); + updateUI(); + } + + /** + * If the editor is <code>JSpinner.DefaultEditor</code>, then forwards the + * call to it, otherwise do nothing. + * + * @throws ParseException DOCUMENT ME! + */ + public void commitEdit() throws ParseException + { + if (editor instanceof DefaultEditor) + ((DefaultEditor) editor).commitEdit(); + } + + /** + * Gets the current editor + * + * @return the current editor + * + * @see #setEditor + */ + public JComponent getEditor() + { + return editor; + } + + /** + * Changes the current editor to the new editor. The old editor is + * removed from the spinner's {@link ChangeEvent} list. + * + * @param editor the new editor (<code>null</code> not permitted. + * + * @throws IllegalArgumentException if <code>editor</code> is + * <code>null</code>. + * + * @see #getEditor + */ + public void setEditor(JComponent editor) + { + if (editor == null) + throw new IllegalArgumentException("editor may not be null"); + + JComponent oldEditor = this.editor; + if (oldEditor instanceof DefaultEditor) + ((DefaultEditor) oldEditor).dismiss(this); + else if (oldEditor instanceof ChangeListener) + removeChangeListener((ChangeListener) oldEditor); + + this.editor = editor; + firePropertyChange("editor", oldEditor, editor); + } + + /** + * Returns the model used by the {@link JSpinner} component. + * + * @return The model. + * + * @see #setModel(SpinnerModel) + */ + public SpinnerModel getModel() + { + return model; + } + + /** + * Sets a new underlying model. + * + * @param newModel the new model to set + * + * @exception IllegalArgumentException if newModel is <code>null</code> + */ + public void setModel(SpinnerModel newModel) + { + if (newModel == null) + throw new IllegalArgumentException(); + + if (model == newModel) + return; + + SpinnerModel oldModel = model; + model = newModel; + firePropertyChange("model", oldModel, newModel); + setEditor(createEditor(model)); + } + + /** + * Gets the next value without changing the current value. + * + * @return the next value + * + * @see javax.swing.SpinnerModel#getNextValue + */ + public Object getNextValue() + { + return model.getNextValue(); + } + + /** + * Gets the previous value without changing the current value. + * + * @return the previous value + * + * @see javax.swing.SpinnerModel#getPreviousValue + */ + public Object getPreviousValue() + { + return model.getPreviousValue(); + } + + /** + * Gets the <code>SpinnerUI</code> that handles this spinner + * + * @return the <code>SpinnerUI</code> + */ + public SpinnerUI getUI() + { + return (SpinnerUI) ui; + } + + /** + * Gets the current value of the spinner, according to the underly model, + * not the UI. + * + * @return the current value + * + * @see javax.swing.SpinnerModel#getValue + */ + public Object getValue() + { + return model.getValue(); + } + + /** + * Sets the value in the model. + * + * @param value the new value. + */ + public void setValue(Object value) + { + model.setValue(value); + } + + /** + * Returns the ID that identifies which look and feel class will be + * the UI delegate for this spinner. + * + * @return <code>"SpinnerUI"</code>. + */ + public String getUIClassID() + { + return "SpinnerUI"; + } + + /** + * This method resets the spinner's UI delegate to the default UI for the + * current look and feel. + */ + public void updateUI() + { + setUI((SpinnerUI) UIManager.getUI(this)); + } + + /** + * Sets the UI delegate for the component. + * + * @param ui The spinner's UI delegate. + */ + public void setUI(SpinnerUI ui) + { + super.setUI(ui); + } + + /** + * Adds a <code>ChangeListener</code> + * + * @param listener the listener to add + */ + public void addChangeListener(ChangeListener listener) + { + listenerList.add(ChangeListener.class, listener); + } + + /** + * Remove a particular listener + * + * @param listener the listener to remove + */ + public void removeChangeListener(ChangeListener listener) + { + listenerList.remove(ChangeListener.class, listener); + } + + /** + * Gets all the <code>ChangeListener</code>s + * + * @return all the <code>ChangeListener</code>s + */ + public ChangeListener[] getChangeListeners() + { + return (ChangeListener[]) listenerList.getListeners(ChangeListener.class); + } + + /** + * Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s + * added to this <code>JSpinner</code> + */ + protected void fireStateChanged() + { + ChangeEvent evt = new ChangeEvent(this); + ChangeListener[] listeners = getChangeListeners(); + + for (int i = 0; i < listeners.length; ++i) + listeners[i].stateChanged(evt); + } + + /** + * Creates an editor that is appropriate for the specified <code>model</code>. + * + * @param model the model. + * + * @return The editor. + */ + protected JComponent createEditor(SpinnerModel model) + { + if (model instanceof SpinnerDateModel) + return new DateEditor(this); + else if (model instanceof SpinnerNumberModel) + return new NumberEditor(this); + else if (model instanceof SpinnerListModel) + return new ListEditor(this); + else + return new DefaultEditor(this); + } +} |