/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.text.*;
import javax.swing.plaf.SpinnerUI;
import java.util.*;
import java.beans.*;
import java.text.*;
import java.io.*;
import java.text.spi.DateFormatProvider;
import java.text.spi.NumberFormatProvider;
import javax.accessibility.*;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.LocaleResources;
A single line input field that lets the user select a
number or an object value from an ordered sequence. Spinners typically
provide a pair of tiny arrow buttons for stepping through the elements
of the sequence. The keyboard up/down arrow keys also cycle through the
elements. The user may also be allowed to type a (legal) value directly
into the spinner. Although combo boxes provide similar functionality,
spinners are sometimes preferred because they don't require a drop down list
that can obscure important data.
A JSpinner
's sequence value is defined by its
SpinnerModel
.
The model
can be specified as a constructor argument and
changed with the model
property. SpinnerModel
classes for some common types are provided: SpinnerListModel
,
SpinnerNumberModel
, and SpinnerDateModel
.
A JSpinner
has a single child component that's
responsible for displaying
and potentially changing the current element or value of
the model, which is called the editor
. The editor is created
by the JSpinner
's constructor and can be changed with the
editor
property. The JSpinner
's editor stays
in sync with the model by listening for ChangeEvent
s. If the
user has changed the value displayed by the editor
it is
possible for the model
's value to differ from that of
the editor
. To make sure the model
has the same
value as the editor use the commitEdit
method, eg:
try {
spinner.commitEdit();
}
catch (ParseException pe) {
// Edited value is invalid, spinner.getValue() will return
// the last valid value, you could revert the spinner to show that:
JComponent editor = spinner.getEditor();
if (editor instanceof DefaultEditor) {
((DefaultEditor)editor).getTextField().setValue(spinner.getValue());
}
// reset the value to some known value:
spinner.setValue(fallbackValue);
// or treat the last valid value as the current, in which
// case you don't need to do anything.
}
return spinner.getValue();
For information and examples of using spinner see
How to Use Spinners,
a section in The Java Tutorial.
Warning: Swing is not thread safe. For more
information see Swing's Threading
Policy.
Warning:
Serialized objects of this class will not be compatible with
future Swing releases. The current serialization support is
appropriate for short term storage or RMI between applications running
the same version of Swing. As of 1.4, support for long term storage
of all JavaBeans™
has been added to the java.beans
package. Please see XMLEncoder
.
Author: Hans Muller, Lynn Monsanto (accessibility) See Also: Since: 1.4
/**
* A single line input field that lets the user select a
* number or an object value from an ordered sequence. Spinners typically
* provide a pair of tiny arrow buttons for stepping through the elements
* of the sequence. The keyboard up/down arrow keys also cycle through the
* elements. The user may also be allowed to type a (legal) value directly
* into the spinner. Although combo boxes provide similar functionality,
* spinners are sometimes preferred because they don't require a drop down list
* that can obscure important data.
* <p>
* A <code>JSpinner</code>'s sequence value is defined by its
* <code>SpinnerModel</code>.
* The <code>model</code> can be specified as a constructor argument and
* changed with the <code>model</code> property. <code>SpinnerModel</code>
* classes for some common types are provided: <code>SpinnerListModel</code>,
* <code>SpinnerNumberModel</code>, and <code>SpinnerDateModel</code>.
* <p>
* A <code>JSpinner</code> has a single child component that's
* responsible for displaying
* and potentially changing the current element or <i>value</i> of
* the model, which is called the <code>editor</code>. The editor is created
* by the <code>JSpinner</code>'s constructor and can be changed with the
* <code>editor</code> property. The <code>JSpinner</code>'s editor stays
* in sync with the model by listening for <code>ChangeEvent</code>s. If the
* user has changed the value displayed by the <code>editor</code> it is
* possible for the <code>model</code>'s value to differ from that of
* the <code>editor</code>. To make sure the <code>model</code> has the same
* value as the editor use the <code>commitEdit</code> method, eg:
* <pre>
* try {
* spinner.commitEdit();
* }
* catch (ParseException pe) {
* // Edited value is invalid, spinner.getValue() will return
* // the last valid value, you could revert the spinner to show that:
* JComponent editor = spinner.getEditor();
* if (editor instanceof DefaultEditor) {
* ((DefaultEditor)editor).getTextField().setValue(spinner.getValue());
* }
* // reset the value to some known value:
* spinner.setValue(fallbackValue);
* // or treat the last valid value as the current, in which
* // case you don't need to do anything.
* }
* return spinner.getValue();
* </pre>
* <p>
* For information and examples of using spinner see
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/spinner.html">How to Use Spinners</a>,
* a section in <em>The Java Tutorial.</em>
* <p>
* <strong>Warning:</strong> Swing is not thread safe. For more
* information see <a
* href="package-summary.html#threading">Swing's Threading
* Policy</a>.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans™
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @see SpinnerModel
* @see AbstractSpinnerModel
* @see SpinnerListModel
* @see SpinnerNumberModel
* @see SpinnerDateModel
* @see JFormattedTextField
*
* @author Hans Muller
* @author Lynn Monsanto (accessibility)
* @since 1.4
*/
@JavaBean(defaultProperty = "UI", description = "A single line input field that lets the user select a number or an object value from an ordered set.")
@SwingContainer(false)
@SuppressWarnings("serial") // Same-version serialization only
public class JSpinner extends JComponent implements Accessible
{
See Also: - getUIClassID
- JComponent.readObject
/**
* @see #getUIClassID
* @see #readObject
*/
private static final String uiClassID = "SpinnerUI";
private static final Action DISABLED_ACTION = new DisabledAction();
private SpinnerModel model;
private JComponent editor;
private ChangeListener modelListener;
private transient ChangeEvent changeEvent;
private boolean editorExplicitlySet = false;
Constructs a spinner for the given model. The spinner has
a set of previous/next buttons, and an editor appropriate
for the model.
Params: - model – a model for the new spinner
Throws: - NullPointerException – if the model is
null
/**
* Constructs a spinner for the given model. The spinner has
* a set of previous/next buttons, and an editor appropriate
* for the model.
*
* @param model a model for the new spinner
* @throws NullPointerException if the model is {@code null}
*/
public JSpinner(SpinnerModel model) {
if (model == null) {
throw new NullPointerException("model cannot be null");
}
this.model = model;
this.editor = createEditor(model);
setUIProperty("opaque",true);
updateUI();
}
Constructs a spinner with an Integer SpinnerNumberModel
with initial value 0 and no minimum or maximum limits.
/**
* Constructs a spinner with an <code>Integer SpinnerNumberModel</code>
* with initial value 0 and no minimum or maximum limits.
*/
public JSpinner() {
this(new SpinnerNumberModel());
}
Returns the look and feel (L&F) object that renders this component.
Returns: the SpinnerUI
object that renders this component
/**
* Returns the look and feel (L&F) object that renders this component.
*
* @return the <code>SpinnerUI</code> object that renders this component
*/
public SpinnerUI getUI() {
return (SpinnerUI)ui;
}
Sets the look and feel (L&F) object that renders this component.
Params: - ui – the
SpinnerUI
L&F object
See Also:
/**
* Sets the look and feel (L&F) object that renders this component.
*
* @param ui the <code>SpinnerUI</code> L&F object
* @see UIDefaults#getUI
*/
public void setUI(SpinnerUI ui) {
super.setUI(ui);
}
Returns the suffix used to construct the name of the look and feel
(L&F) class used to render this component.
See Also: Returns: the string "SpinnerUI"
/**
* Returns the suffix used to construct the name of the look and feel
* (L&F) class used to render this component.
*
* @return the string "SpinnerUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
@BeanProperty(bound = false)
public String getUIClassID() {
return uiClassID;
}
Resets the UI property with the value from the current look and feel.
See Also: - getUI.getUI
/**
* Resets the UI property with the value from the current look and feel.
*
* @see UIManager#getUI
*/
public void updateUI() {
setUI((SpinnerUI)UIManager.getUI(this));
invalidate();
}
This method is called by the constructors to create the
JComponent
that displays the current value of the sequence. The editor may
also allow the user to enter an element of the sequence directly.
An editor must listen for ChangeEvents
on the
model
and keep the value it displays
in sync with the value of the model.
Subclasses may override this method to add support for new
SpinnerModel
classes. Alternatively one can just
replace the editor created here with the setEditor
method. The default mapping from model type to editor is:
-
SpinnerNumberModel => JSpinner.NumberEditor
-
SpinnerDateModel => JSpinner.DateEditor
-
SpinnerListModel => JSpinner.ListEditor
- all others =>
JSpinner.DefaultEditor
Params: - model – the value of getModel
See Also: Returns: a component that displays the current value of the sequence
/**
* This method is called by the constructors to create the
* <code>JComponent</code>
* that displays the current value of the sequence. The editor may
* also allow the user to enter an element of the sequence directly.
* An editor must listen for <code>ChangeEvents</code> on the
* <code>model</code> and keep the value it displays
* in sync with the value of the model.
* <p>
* Subclasses may override this method to add support for new
* <code>SpinnerModel</code> classes. Alternatively one can just
* replace the editor created here with the <code>setEditor</code>
* method. The default mapping from model type to editor is:
* <ul>
* <li> <code>SpinnerNumberModel => JSpinner.NumberEditor</code>
* <li> <code>SpinnerDateModel => JSpinner.DateEditor</code>
* <li> <code>SpinnerListModel => JSpinner.ListEditor</code>
* <li> <i>all others</i> => <code>JSpinner.DefaultEditor</code>
* </ul>
*
* @return a component that displays the current value of the sequence
* @param model the value of getModel
* @see #getModel
* @see #setEditor
*/
protected JComponent createEditor(SpinnerModel model) {
if (model instanceof SpinnerDateModel) {
return new DateEditor(this);
}
else if (model instanceof SpinnerListModel) {
return new ListEditor(this);
}
else if (model instanceof SpinnerNumberModel) {
return new NumberEditor(this);
}
else {
return new DefaultEditor(this);
}
}
Changes the model that represents the value of this spinner.
If the editor property has not been explicitly set,
the editor property is (implicitly) set after the "model"
PropertyChangeEvent
has been fired. The editor
property is set to the value returned by createEditor
,
as in:
setEditor(createEditor(model));
Params: - model – the new
SpinnerModel
Throws: - IllegalArgumentException – if model is
null
See Also:
/**
* Changes the model that represents the value of this spinner.
* If the editor property has not been explicitly set,
* the editor property is (implicitly) set after the <code>"model"</code>
* <code>PropertyChangeEvent</code> has been fired. The editor
* property is set to the value returned by <code>createEditor</code>,
* as in:
* <pre>
* setEditor(createEditor(model));
* </pre>
*
* @param model the new <code>SpinnerModel</code>
* @see #getModel
* @see #getEditor
* @see #setEditor
* @throws IllegalArgumentException if model is <code>null</code>
*/
@BeanProperty(visualUpdate = true, description
= "Model that represents the value of this spinner.")
public void setModel(SpinnerModel model) {
if (model == null) {
throw new IllegalArgumentException("null model");
}
if (!model.equals(this.model)) {
SpinnerModel oldModel = this.model;
this.model = model;
if (modelListener != null) {
oldModel.removeChangeListener(modelListener);
this.model.addChangeListener(modelListener);
}
firePropertyChange("model", oldModel, model);
if (!editorExplicitlySet) {
setEditor(createEditor(model)); // sets editorExplicitlySet true
editorExplicitlySet = false;
}
repaint();
revalidate();
}
}
Returns the SpinnerModel
that defines
this spinners sequence of values.
See Also: Returns: the value of the model property
/**
* Returns the <code>SpinnerModel</code> that defines
* this spinners sequence of values.
*
* @return the value of the model property
* @see #setModel
*/
public SpinnerModel getModel() {
return model;
}
Returns the current value of the model, typically
this value is displayed by the editor
. If the
user has changed the value displayed by the editor
it is
possible for the model
's value to differ from that of
the editor
, refer to the class level javadoc for examples
of how to deal with this.
This method simply delegates to the model
.
It is equivalent to:
getModel().getValue()
See Also: Returns: the current value of the model
/**
* Returns the current value of the model, typically
* this value is displayed by the <code>editor</code>. If the
* user has changed the value displayed by the <code>editor</code> it is
* possible for the <code>model</code>'s value to differ from that of
* the <code>editor</code>, refer to the class level javadoc for examples
* of how to deal with this.
* <p>
* This method simply delegates to the <code>model</code>.
* It is equivalent to:
* <pre>
* getModel().getValue()
* </pre>
*
* @return the current value of the model
* @see #setValue
* @see SpinnerModel#getValue
*/
public Object getValue() {
return getModel().getValue();
}
Changes current value of the model, typically
this value is displayed by the editor
.
If the SpinnerModel
implementation
doesn't support the specified value then an
IllegalArgumentException
is thrown.
This method simply delegates to the model
.
It is equivalent to:
getModel().setValue(value)
Params: - value – new value for the spinner
Throws: - IllegalArgumentException – if
value
isn't allowed
See Also:
/**
* Changes current value of the model, typically
* this value is displayed by the <code>editor</code>.
* If the <code>SpinnerModel</code> implementation
* doesn't support the specified value then an
* <code>IllegalArgumentException</code> is thrown.
* <p>
* This method simply delegates to the <code>model</code>.
* It is equivalent to:
* <pre>
* getModel().setValue(value)
* </pre>
*
* @param value new value for the spinner
* @throws IllegalArgumentException if <code>value</code> isn't allowed
* @see #getValue
* @see SpinnerModel#setValue
*/
public void setValue(Object value) {
getModel().setValue(value);
}
Returns the object in the sequence that comes after the object returned
by getValue()
. If the end of the sequence has been reached
then return null
.
Calling this method does not effect value
.
This method simply delegates to the model
.
It is equivalent to:
getModel().getNextValue()
See Also: Returns: the next legal value or null
if one doesn't exist
/**
* Returns the object in the sequence that comes after the object returned
* by <code>getValue()</code>. If the end of the sequence has been reached
* then return <code>null</code>.
* Calling this method does not effect <code>value</code>.
* <p>
* This method simply delegates to the <code>model</code>.
* It is equivalent to:
* <pre>
* getModel().getNextValue()
* </pre>
*
* @return the next legal value or <code>null</code> if one doesn't exist
* @see #getValue
* @see #getPreviousValue
* @see SpinnerModel#getNextValue
*/
@BeanProperty(bound = false)
public Object getNextValue() {
return getModel().getNextValue();
}
We pass Change
events along to the listeners with the
the slider (instead of the model itself) as the event source.
/**
* We pass <code>Change</code> events along to the listeners with the
* the slider (instead of the model itself) as the event source.
*/
private class ModelListener implements ChangeListener, Serializable {
public void stateChanged(ChangeEvent e) {
fireStateChanged();
}
}
Adds a listener to the list that is notified each time a change
to the model occurs. The source of ChangeEvents
delivered to ChangeListeners
will be this
JSpinner
. Note also that replacing the model
will not affect listeners added directly to JSpinner.
Applications can add listeners to the model directly. In that
case is that the source of the event would be the
SpinnerModel
.
Params: - listener – the
ChangeListener
to add
See Also:
/**
* Adds a listener to the list that is notified each time a change
* to the model occurs. The source of <code>ChangeEvents</code>
* delivered to <code>ChangeListeners</code> will be this
* <code>JSpinner</code>. Note also that replacing the model
* will not affect listeners added directly to JSpinner.
* Applications can add listeners to the model directly. In that
* case is that the source of the event would be the
* <code>SpinnerModel</code>.
*
* @param listener the <code>ChangeListener</code> to add
* @see #removeChangeListener
* @see #getModel
*/
public void addChangeListener(ChangeListener listener) {
if (modelListener == null) {
modelListener = new ModelListener();
getModel().addChangeListener(modelListener);
}
listenerList.add(ChangeListener.class, listener);
}
Removes a ChangeListener
from this spinner.
Params: - listener – the
ChangeListener
to remove
See Also:
/**
* Removes a <code>ChangeListener</code> from this spinner.
*
* @param listener the <code>ChangeListener</code> to remove
* @see #fireStateChanged
* @see #addChangeListener
*/
public void removeChangeListener(ChangeListener listener) {
listenerList.remove(ChangeListener.class, listener);
}
Returns an array of all the ChangeListener
s added
to this JSpinner with addChangeListener().
Returns: all of the ChangeListener
s added or an empty
array if no listeners have been added Since: 1.4
/**
* Returns an array of all the <code>ChangeListener</code>s added
* to this JSpinner with addChangeListener().
*
* @return all of the <code>ChangeListener</code>s added or an empty
* array if no listeners have been added
* @since 1.4
*/
@BeanProperty(bound = false)
public ChangeListener[] getChangeListeners() {
return listenerList.getListeners(ChangeListener.class);
}
Sends a ChangeEvent
, whose source is this
JSpinner
, to each ChangeListener
.
When a ChangeListener
has been added
to the spinner, this method is called each time
a ChangeEvent
is received from the model.
See Also: - addChangeListener
- removeChangeListener
- EventListenerList
/**
* Sends a <code>ChangeEvent</code>, whose source is this
* <code>JSpinner</code>, to each <code>ChangeListener</code>.
* When a <code>ChangeListener</code> has been added
* to the spinner, this method is called each time
* a <code>ChangeEvent</code> is received from the model.
*
* @see #addChangeListener
* @see #removeChangeListener
* @see EventListenerList
*/
protected void fireStateChanged() {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChangeListener.class) {
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
}
}
}
Returns the object in the sequence that comes
before the object returned by getValue()
.
If the end of the sequence has been reached then
return null
. Calling this method does
not effect value
.
This method simply delegates to the model
.
It is equivalent to:
getModel().getPreviousValue()
See Also: Returns: the previous legal value or null
if one doesn't exist
/**
* Returns the object in the sequence that comes
* before the object returned by <code>getValue()</code>.
* If the end of the sequence has been reached then
* return <code>null</code>. Calling this method does
* not effect <code>value</code>.
* <p>
* This method simply delegates to the <code>model</code>.
* It is equivalent to:
* <pre>
* getModel().getPreviousValue()
* </pre>
*
* @return the previous legal value or <code>null</code>
* if one doesn't exist
* @see #getValue
* @see #getNextValue
* @see SpinnerModel#getPreviousValue
*/
@BeanProperty(bound = false)
public Object getPreviousValue() {
return getModel().getPreviousValue();
}
Changes the JComponent
that displays the current value
of the SpinnerModel
. It is the responsibility of this
method to disconnect the old editor from the model and to
connect the new editor. This may mean removing the
old editors ChangeListener
from the model or the
spinner itself and adding one for the new editor.
Params: - editor – the new editor
Throws: - IllegalArgumentException – if editor is
null
See Also:
/**
* Changes the <code>JComponent</code> that displays the current value
* of the <code>SpinnerModel</code>. It is the responsibility of this
* method to <i>disconnect</i> the old editor from the model and to
* connect the new editor. This may mean removing the
* old editors <code>ChangeListener</code> from the model or the
* spinner itself and adding one for the new editor.
*
* @param editor the new editor
* @see #getEditor
* @see #createEditor
* @see #getModel
* @throws IllegalArgumentException if editor is <code>null</code>
*/
@BeanProperty(visualUpdate = true, description
= "JComponent that displays the current value of the model")
public void setEditor(JComponent editor) {
if (editor == null) {
throw new IllegalArgumentException("null editor");
}
if (!editor.equals(this.editor)) {
JComponent oldEditor = this.editor;
this.editor = editor;
if (oldEditor instanceof DefaultEditor) {
((DefaultEditor)oldEditor).dismiss(this);
}
editorExplicitlySet = true;
firePropertyChange("editor", oldEditor, editor);
revalidate();
repaint();
}
}
Returns the component that displays and potentially
changes the model's value.
See Also: Returns: the component that displays and potentially
changes the model's value
/**
* Returns the component that displays and potentially
* changes the model's value.
*
* @return the component that displays and potentially
* changes the model's value
* @see #setEditor
* @see #createEditor
*/
public JComponent getEditor() {
return editor;
}
Commits the currently edited value to the SpinnerModel
.
If the editor is an instance of DefaultEditor
, the
call if forwarded to the editor, otherwise this does nothing.
Throws: - ParseException – if the currently edited value couldn't
be committed.
/**
* Commits the currently edited value to the <code>SpinnerModel</code>.
* <p>
* If the editor is an instance of <code>DefaultEditor</code>, the
* call if forwarded to the editor, otherwise this does nothing.
*
* @throws ParseException if the currently edited value couldn't
* be committed.
*/
public void commitEdit() throws ParseException {
JComponent editor = getEditor();
if (editor instanceof DefaultEditor) {
((DefaultEditor)editor).commitEdit();
}
}
/*
* See readObject and writeObject in JComponent for more
* information about serialization in Swing.
*
* @param s Stream to write to
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if (getUIClassID().equals(uiClassID)) {
byte count = JComponent.getWriteObjCounter(this);
JComponent.setWriteObjCounter(this, --count);
if (count == 0 && ui != null) {
ui.installUI(this);
}
}
}
A simple base class for more specialized editors
that displays a read-only view of the model's current
value with a JFormattedTextField
. Subclasses
can configure the JFormattedTextField
to create
an editor that's appropriate for the type of model they
support and they may want to override
the stateChanged
and propertyChanged
methods, which keep the model and the text field in sync.
This class defines a dismiss
method that removes the
editors ChangeListener
from the JSpinner
that it's part of. The setEditor
method knows about
DefaultEditor.dismiss
, so if the developer
replaces an editor that's derived from JSpinner.DefaultEditor
its ChangeListener
connection back to the
JSpinner
will be removed. However after that,
it's up to the developer to manage their editor listeners.
Similarly, if a subclass overrides createEditor
,
it's up to the subclasser to deal with their editor
subsequently being replaced (with setEditor
).
We expect that in most cases, and in editor installed
with setEditor
or created by a createEditor
override, will not be replaced anyway.
This class is the LayoutManager
for it's single
JFormattedTextField
child. By default the
child is just centered with the parents insets.
Since: 1.4
/**
* A simple base class for more specialized editors
* that displays a read-only view of the model's current
* value with a <code>JFormattedTextField</code>. Subclasses
* can configure the <code>JFormattedTextField</code> to create
* an editor that's appropriate for the type of model they
* support and they may want to override
* the <code>stateChanged</code> and <code>propertyChanged</code>
* methods, which keep the model and the text field in sync.
* <p>
* This class defines a <code>dismiss</code> method that removes the
* editors <code>ChangeListener</code> from the <code>JSpinner</code>
* that it's part of. The <code>setEditor</code> method knows about
* <code>DefaultEditor.dismiss</code>, so if the developer
* replaces an editor that's derived from <code>JSpinner.DefaultEditor</code>
* its <code>ChangeListener</code> connection back to the
* <code>JSpinner</code> will be removed. However after that,
* it's up to the developer to manage their editor listeners.
* Similarly, if a subclass overrides <code>createEditor</code>,
* it's up to the subclasser to deal with their editor
* subsequently being replaced (with <code>setEditor</code>).
* We expect that in most cases, and in editor installed
* with <code>setEditor</code> or created by a <code>createEditor</code>
* override, will not be replaced anyway.
* <p>
* This class is the <code>LayoutManager</code> for it's single
* <code>JFormattedTextField</code> child. By default the
* child is just centered with the parents insets.
* @since 1.4
*/
public static class DefaultEditor extends JPanel
implements ChangeListener, PropertyChangeListener, LayoutManager
{
Constructs an editor component for the specified JSpinner
.
This DefaultEditor
is it's own layout manager and
it is added to the spinner's ChangeListener
list.
The constructor creates a single JFormattedTextField
child,
initializes it's value to be the spinner model's current value
and adds it to this
DefaultEditor
.
Params: - spinner – the spinner whose model
this
editor will monitor
See Also:
/**
* Constructs an editor component for the specified <code>JSpinner</code>.
* This <code>DefaultEditor</code> is it's own layout manager and
* it is added to the spinner's <code>ChangeListener</code> list.
* The constructor creates a single <code>JFormattedTextField</code> child,
* initializes it's value to be the spinner model's current value
* and adds it to <code>this</code> <code>DefaultEditor</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @see #getTextField
* @see JSpinner#addChangeListener
*/
public DefaultEditor(JSpinner spinner) {
super(null);
JFormattedTextField ftf = new JFormattedTextField();
ftf.setName("Spinner.formattedTextField");
ftf.setValue(spinner.getValue());
ftf.addPropertyChangeListener(this);
ftf.setEditable(false);
ftf.setInheritsPopupMenu(true);
String toolTipText = spinner.getToolTipText();
if (toolTipText != null) {
ftf.setToolTipText(toolTipText);
}
add(ftf);
setLayout(this);
spinner.addChangeListener(this);
// We want the spinner's increment/decrement actions to be
// active vs those of the JFormattedTextField. As such we
// put disabled actions in the JFormattedTextField's actionmap.
// A binding to a disabled action is treated as a nonexistant
// binding.
ActionMap ftfMap = ftf.getActionMap();
if (ftfMap != null) {
ftfMap.put("increment", DISABLED_ACTION);
ftfMap.put("decrement", DISABLED_ACTION);
}
}
Disconnect this
editor from the specified
JSpinner
. By default, this method removes
itself from the spinners ChangeListener
list.
Params: - spinner – the
JSpinner
to disconnect this
editor from; the same spinner as was passed to the constructor.
/**
* Disconnect <code>this</code> editor from the specified
* <code>JSpinner</code>. By default, this method removes
* itself from the spinners <code>ChangeListener</code> list.
*
* @param spinner the <code>JSpinner</code> to disconnect this
* editor from; the same spinner as was passed to the constructor.
*/
public void dismiss(JSpinner spinner) {
spinner.removeChangeListener(this);
}
Returns the JSpinner
ancestor of this editor or
null
if none of the ancestors are a
JSpinner
.
Typically the editor's parent is a JSpinner
however
subclasses of JSpinner
may override the
the createEditor
method and insert one or more containers
between the JSpinner
and it's editor.
See Also: Returns: JSpinner
ancestor; null
if none of the ancestors are a JSpinner
/**
* Returns the <code>JSpinner</code> ancestor of this editor or
* <code>null</code> if none of the ancestors are a
* <code>JSpinner</code>.
* Typically the editor's parent is a <code>JSpinner</code> however
* subclasses of <code>JSpinner</code> may override the
* the <code>createEditor</code> method and insert one or more containers
* between the <code>JSpinner</code> and it's editor.
*
* @return <code>JSpinner</code> ancestor; <code>null</code>
* if none of the ancestors are a <code>JSpinner</code>
*
* @see JSpinner#createEditor
*/
public JSpinner getSpinner() {
for (Component c = this; c != null; c = c.getParent()) {
if (c instanceof JSpinner) {
return (JSpinner)c;
}
}
return null;
}
Returns the JFormattedTextField
child of this
editor. By default the text field is the first and only
child of editor.
See Also: - getSpinner
- getModel
Returns: the JFormattedTextField
that gives the user
access to the SpinnerDateModel's
value.
/**
* Returns the <code>JFormattedTextField</code> child of this
* editor. By default the text field is the first and only
* child of editor.
*
* @return the <code>JFormattedTextField</code> that gives the user
* access to the <code>SpinnerDateModel's</code> value.
* @see #getSpinner
* @see #getModel
*/
public JFormattedTextField getTextField() {
return (JFormattedTextField)getComponent(0);
}
This method is called when the spinner's model's state changes.
It sets the value
of the text field to the current
value of the spinners model.
Params: - e – the
ChangeEvent
whose source is the
JSpinner
whose model has changed.
See Also:
/**
* This method is called when the spinner's model's state changes.
* It sets the <code>value</code> of the text field to the current
* value of the spinners model.
*
* @param e the <code>ChangeEvent</code> whose source is the
* <code>JSpinner</code> whose model has changed.
* @see #getTextField
* @see JSpinner#getValue
*/
public void stateChanged(ChangeEvent e) {
JSpinner spinner = (JSpinner)(e.getSource());
getTextField().setValue(spinner.getValue());
}
Called by the JFormattedTextField
PropertyChangeListener
. When the "value"
property changes, which implies that the user has typed a new
number, we set the value of the spinners model.
This class ignores PropertyChangeEvents
whose
source is not the JFormattedTextField
, so subclasses
may safely make this
DefaultEditor
a
PropertyChangeListener
on other objects.
Params: - e – the
PropertyChangeEvent
whose source is
the JFormattedTextField
created by this class.
See Also:
/**
* Called by the <code>JFormattedTextField</code>
* <code>PropertyChangeListener</code>. When the <code>"value"</code>
* property changes, which implies that the user has typed a new
* number, we set the value of the spinners model.
* <p>
* This class ignores <code>PropertyChangeEvents</code> whose
* source is not the <code>JFormattedTextField</code>, so subclasses
* may safely make <code>this</code> <code>DefaultEditor</code> a
* <code>PropertyChangeListener</code> on other objects.
*
* @param e the <code>PropertyChangeEvent</code> whose source is
* the <code>JFormattedTextField</code> created by this class.
* @see #getTextField
*/
public void propertyChange(PropertyChangeEvent e)
{
JSpinner spinner = getSpinner();
if (spinner == null) {
// Indicates we aren't installed anywhere.
return;
}
Object source = e.getSource();
String name = e.getPropertyName();
if (source instanceof JFormattedTextField) {
if ("value".equals(name)) {
Object lastValue = spinner.getValue();
// Try to set the new value
try {
spinner.setValue(getTextField().getValue());
} catch (IllegalArgumentException iae) {
// SpinnerModel didn't like new value, reset
try {
((JFormattedTextField)source).setValue(lastValue);
} catch (IllegalArgumentException iae2) {
// Still bogus, nothing else we can do, the
// SpinnerModel and JFormattedTextField are now out
// of sync.
}
}
} else if ("font".equals(name)) {
Object newfont = e.getNewValue();
if (newfont instanceof UIResource) {
// The text field font must match the JSpinner font if
// the text field font was not set by the user
Font font = spinner.getFont();
if (!newfont.equals(font)) {
getTextField().setFont(font == null ? null : new FontUIResource(font));
}
}
}
}
}
This LayoutManager
method does nothing. We're
only managing a single child and there's no support
for layout constraints.
Params: - name – ignored
- child – ignored
/**
* This <code>LayoutManager</code> method does nothing. We're
* only managing a single child and there's no support
* for layout constraints.
*
* @param name ignored
* @param child ignored
*/
public void addLayoutComponent(String name, Component child) {
}
This LayoutManager
method does nothing. There
isn't any per-child state.
Params: - child – ignored
/**
* This <code>LayoutManager</code> method does nothing. There
* isn't any per-child state.
*
* @param child ignored
*/
public void removeLayoutComponent(Component child) {
}
Returns the size of the parents insets.
/**
* Returns the size of the parents insets.
*/
private Dimension insetSize(Container parent) {
Insets insets = parent.getInsets();
int w = insets.left + insets.right;
int h = insets.top + insets.bottom;
return new Dimension(w, h);
}
Returns the preferred size of first (and only) child plus the
size of the parents insets.
Params: - parent – the Container that's managing the layout
Returns: the preferred dimensions to lay out the subcomponents
of the specified container.
/**
* Returns the preferred size of first (and only) child plus the
* size of the parents insets.
*
* @param parent the Container that's managing the layout
* @return the preferred dimensions to lay out the subcomponents
* of the specified container.
*/
public Dimension preferredLayoutSize(Container parent) {
Dimension preferredSize = insetSize(parent);
if (parent.getComponentCount() > 0) {
Dimension childSize = getComponent(0).getPreferredSize();
preferredSize.width += childSize.width;
preferredSize.height += childSize.height;
}
return preferredSize;
}
Returns the minimum size of first (and only) child plus the
size of the parents insets.
Params: - parent – the Container that's managing the layout
Returns: the minimum dimensions needed to lay out the subcomponents
of the specified container.
/**
* Returns the minimum size of first (and only) child plus the
* size of the parents insets.
*
* @param parent the Container that's managing the layout
* @return the minimum dimensions needed to lay out the subcomponents
* of the specified container.
*/
public Dimension minimumLayoutSize(Container parent) {
Dimension minimumSize = insetSize(parent);
if (parent.getComponentCount() > 0) {
Dimension childSize = getComponent(0).getMinimumSize();
minimumSize.width += childSize.width;
minimumSize.height += childSize.height;
}
return minimumSize;
}
Resize the one (and only) child to completely fill the area
within the parents insets.
/**
* Resize the one (and only) child to completely fill the area
* within the parents insets.
*/
public void layoutContainer(Container parent) {
if (parent.getComponentCount() > 0) {
Insets insets = parent.getInsets();
int w = parent.getWidth() - (insets.left + insets.right);
int h = parent.getHeight() - (insets.top + insets.bottom);
getComponent(0).setBounds(insets.left, insets.top, w, h);
}
}
Pushes the currently edited value to the SpinnerModel
.
The default implementation invokes commitEdit
on the
JFormattedTextField
.
Throws: - ParseException – if the edited value is not legal
/**
* Pushes the currently edited value to the <code>SpinnerModel</code>.
* <p>
* The default implementation invokes <code>commitEdit</code> on the
* <code>JFormattedTextField</code>.
*
* @throws ParseException if the edited value is not legal
*/
public void commitEdit() throws ParseException {
// If the value in the JFormattedTextField is legal, this will have
// the result of pushing the value to the SpinnerModel
// by way of the <code>propertyChange</code> method.
JFormattedTextField ftf = getTextField();
ftf.commitEdit();
}
Returns the baseline.
Throws: - IllegalArgumentException – {@inheritDoc}
See Also: Since: 1.6
/**
* Returns the baseline.
*
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int,int)
* @see javax.swing.JComponent#getBaselineResizeBehavior()
* @since 1.6
*/
public int getBaseline(int width, int height) {
// check size.
super.getBaseline(width, height);
Insets insets = getInsets();
width = width - insets.left - insets.right;
height = height - insets.top - insets.bottom;
int baseline = getComponent(0).getBaseline(width, height);
if (baseline >= 0) {
return baseline + insets.top;
}
return -1;
}
Returns an enum indicating how the baseline of the component
changes as the size changes.
Throws: - NullPointerException – {@inheritDoc}
See Also: Since: 1.6
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public BaselineResizeBehavior getBaselineResizeBehavior() {
return getComponent(0).getBaselineResizeBehavior();
}
}
This subclass of javax.swing.DateFormatter maps the minimum/maximum
properties to the start/end properties of a SpinnerDateModel.
/**
* This subclass of javax.swing.DateFormatter maps the minimum/maximum
* properties to the start/end properties of a SpinnerDateModel.
*/
private static class DateEditorFormatter extends DateFormatter {
private final SpinnerDateModel model;
DateEditorFormatter(SpinnerDateModel model, DateFormat format) {
super(format);
this.model = model;
}
@Override
@SuppressWarnings("unchecked")
public void setMinimum(Comparable<?> min) {
model.setStart((Comparable<Date>)min);
}
@Override
public Comparable<Date> getMinimum() {
return model.getStart();
}
@Override
@SuppressWarnings("unchecked")
public void setMaximum(Comparable<?> max) {
model.setEnd((Comparable<Date>)max);
}
@Override
public Comparable<Date> getMaximum() {
return model.getEnd();
}
}
An editor for a JSpinner
whose model is a
SpinnerDateModel
. The value of the editor is
displayed with a JFormattedTextField
whose format
is defined by a DateFormatter
instance whose
minimum
and maximum
properties
are mapped to the SpinnerDateModel
.
Since: 1.4
/**
* An editor for a <code>JSpinner</code> whose model is a
* <code>SpinnerDateModel</code>. The value of the editor is
* displayed with a <code>JFormattedTextField</code> whose format
* is defined by a <code>DateFormatter</code> instance whose
* <code>minimum</code> and <code>maximum</code> properties
* are mapped to the <code>SpinnerDateModel</code>.
* @since 1.4
*/
// PENDING(hmuller): more example javadoc
public static class DateEditor extends DefaultEditor
{
// This is here until SimpleDateFormat gets a constructor that
// takes a Locale: 4923525
private static String getDefaultPattern(Locale loc) {
LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, loc);
LocaleResources lr = adapter.getLocaleResources(loc);
if (lr == null) {
lr = LocaleProviderAdapter.forJRE().getLocaleResources(loc);
}
return lr.getDateTimePattern(DateFormat.SHORT, DateFormat.SHORT, null);
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerDateModel
with a JFormattedTextField
. This
DateEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerDateModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerDateModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>DateEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerDateModel</code>
*
* @see #getModel
* @see #getFormat
* @see SpinnerDateModel
*/
public DateEditor(JSpinner spinner) {
this(spinner, getDefaultPattern(spinner.getLocale()));
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerDateModel
with a JFormattedTextField
. This
DateEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor - dateFormatPattern – the initial pattern for the
SimpleDateFormat
object that's used to display
and parse the value of the text field.
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerDateModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerDateModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>DateEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @param dateFormatPattern the initial pattern for the
* <code>SimpleDateFormat</code> object that's used to display
* and parse the value of the text field.
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerDateModel</code>
*
* @see #getModel
* @see #getFormat
* @see SpinnerDateModel
* @see java.text.SimpleDateFormat
*/
public DateEditor(JSpinner spinner, String dateFormatPattern) {
this(spinner, new SimpleDateFormat(dateFormatPattern,
spinner.getLocale()));
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerDateModel
with a JFormattedTextField
. This
DateEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor
will monitor - format –
DateFormat
object that's used to display
and parse the value of the text field.
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerDateModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerDateModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>DateEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor
* will monitor
* @param format <code>DateFormat</code> object that's used to display
* and parse the value of the text field.
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerDateModel</code>
*
* @see #getModel
* @see #getFormat
* @see SpinnerDateModel
* @see java.text.SimpleDateFormat
*/
private DateEditor(JSpinner spinner, DateFormat format) {
super(spinner);
if (!(spinner.getModel() instanceof SpinnerDateModel)) {
throw new IllegalArgumentException(
"model not a SpinnerDateModel");
}
SpinnerDateModel model = (SpinnerDateModel)spinner.getModel();
DateFormatter formatter = new DateEditorFormatter(model, format);
DefaultFormatterFactory factory = new DefaultFormatterFactory(
formatter);
JFormattedTextField ftf = getTextField();
ftf.setEditable(true);
ftf.setFormatterFactory(factory);
/* 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.getStart());
String minString = formatter.valueToString(model.getEnd());
ftf.setColumns(Math.max(maxString.length(),
minString.length()));
}
catch (ParseException e) {
// PENDING: hmuller
}
}
Returns the java.text.SimpleDateFormat
object the
JFormattedTextField
uses to parse and format
numbers.
See Also: Returns: the value of getTextField().getFormatter().getFormat()
.
/**
* Returns the <code>java.text.SimpleDateFormat</code> object the
* <code>JFormattedTextField</code> uses to parse and format
* numbers.
*
* @return the value of <code>getTextField().getFormatter().getFormat()</code>.
* @see #getTextField
* @see java.text.SimpleDateFormat
*/
public SimpleDateFormat getFormat() {
return (SimpleDateFormat)((DateFormatter)(getTextField().getFormatter())).getFormat();
}
Return our spinner ancestor's SpinnerDateModel
.
See Also: Returns: getSpinner().getModel()
/**
* Return our spinner ancestor's <code>SpinnerDateModel</code>.
*
* @return <code>getSpinner().getModel()</code>
* @see #getSpinner
* @see #getTextField
*/
public SpinnerDateModel getModel() {
return (SpinnerDateModel)(getSpinner().getModel());
}
}
This subclass of javax.swing.NumberFormatter maps the minimum/maximum
properties to a SpinnerNumberModel and initializes the valueClass
of the NumberFormatter to match the type of the initial models value.
/**
* This subclass of javax.swing.NumberFormatter maps the minimum/maximum
* properties to a SpinnerNumberModel and initializes the valueClass
* of the NumberFormatter to match the type of the initial models value.
*/
private static class NumberEditorFormatter extends NumberFormatter {
private final SpinnerNumberModel model;
NumberEditorFormatter(SpinnerNumberModel 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();
}
}
An editor for a JSpinner
whose model is a
SpinnerNumberModel
. The value of the editor is
displayed with a JFormattedTextField
whose format
is defined by a NumberFormatter
instance whose
minimum
and maximum
properties
are mapped to the SpinnerNumberModel
.
Since: 1.4
/**
* An editor for a <code>JSpinner</code> whose model is a
* <code>SpinnerNumberModel</code>. The value of the editor is
* displayed with a <code>JFormattedTextField</code> whose format
* is defined by a <code>NumberFormatter</code> instance whose
* <code>minimum</code> and <code>maximum</code> properties
* are mapped to the <code>SpinnerNumberModel</code>.
* @since 1.4
*/
// PENDING(hmuller): more example javadoc
public static class NumberEditor extends DefaultEditor
{
// This is here until DecimalFormat gets a constructor that
// takes a Locale: 4923525
private static String getDefaultPattern(Locale locale) {
// Get the pattern for the default locale.
LocaleProviderAdapter adapter;
adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
locale);
LocaleResources lr = adapter.getLocaleResources(locale);
if (lr == null) {
lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
}
String[] all = lr.getNumberPatterns();
return all[0];
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerNumberModel
with a JFormattedTextField
. This
NumberEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerNumberModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerNumberModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>NumberEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerNumberModel</code>
*
* @see #getModel
* @see #getFormat
* @see SpinnerNumberModel
*/
public NumberEditor(JSpinner spinner) {
this(spinner, getDefaultPattern(spinner.getLocale()));
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerNumberModel
with a JFormattedTextField
. This
NumberEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor - decimalFormatPattern – the initial pattern for the
DecimalFormat
object that's used to display
and parse the value of the text field.
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerNumberModel
or if
decimalFormatPattern
is not a legal
argument to DecimalFormat
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerNumberModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>NumberEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @param decimalFormatPattern the initial pattern for the
* <code>DecimalFormat</code> object that's used to display
* and parse the value of the text field.
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerNumberModel</code> or if
* <code>decimalFormatPattern</code> is not a legal
* argument to <code>DecimalFormat</code>
*
* @see #getTextField
* @see SpinnerNumberModel
* @see java.text.DecimalFormat
*/
public NumberEditor(JSpinner spinner, String decimalFormatPattern) {
this(spinner, new DecimalFormat(decimalFormatPattern));
}
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerNumberModel
with a JFormattedTextField
. This
NumberEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor - format – the initial pattern for the
DecimalFormat
object that's used to display
and parse the value of the text field.
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerNumberModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerNumberModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>NumberEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @param format the initial pattern for the
* <code>DecimalFormat</code> object that's used to display
* and parse the value of the text field.
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerNumberModel</code>
*
* @see #getTextField
* @see SpinnerNumberModel
* @see java.text.DecimalFormat
*/
private NumberEditor(JSpinner spinner, DecimalFormat format) {
super(spinner);
if (!(spinner.getModel() instanceof SpinnerNumberModel)) {
throw new IllegalArgumentException(
"model not a SpinnerNumberModel");
}
SpinnerNumberModel model = (SpinnerNumberModel)spinner.getModel();
NumberFormatter formatter = new NumberEditorFormatter(model,
format);
DefaultFormatterFactory factory = new DefaultFormatterFactory(
formatter);
JFormattedTextField ftf = getTextField();
ftf.setEditable(true);
ftf.setFormatterFactory(factory);
// Change the text orientation for the NumberEditor
ftf.setHorizontalAlignment(JTextField.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
}
}
Returns the java.text.DecimalFormat
object the
JFormattedTextField
uses to parse and format
numbers.
See Also: Returns: the value of getTextField().getFormatter().getFormat()
.
/**
* Returns the <code>java.text.DecimalFormat</code> object the
* <code>JFormattedTextField</code> uses to parse and format
* numbers.
*
* @return the value of <code>getTextField().getFormatter().getFormat()</code>.
* @see #getTextField
* @see java.text.DecimalFormat
*/
public DecimalFormat getFormat() {
return (DecimalFormat)((NumberFormatter)(getTextField().getFormatter())).getFormat();
}
Return our spinner ancestor's SpinnerNumberModel
.
See Also: Returns: getSpinner().getModel()
/**
* Return our spinner ancestor's <code>SpinnerNumberModel</code>.
*
* @return <code>getSpinner().getModel()</code>
* @see #getSpinner
* @see #getTextField
*/
public SpinnerNumberModel getModel() {
return (SpinnerNumberModel)(getSpinner().getModel());
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
@Override
public void setComponentOrientation(ComponentOrientation o) {
super.setComponentOrientation(o);
getTextField().setHorizontalAlignment(
o.isLeftToRight() ? JTextField.RIGHT : JTextField.LEFT);
}
}
An editor for a JSpinner
whose model is a
SpinnerListModel
.
Since: 1.4
/**
* An editor for a <code>JSpinner</code> whose model is a
* <code>SpinnerListModel</code>.
* @since 1.4
*/
public static class ListEditor extends DefaultEditor
{
Construct a JSpinner
editor that supports displaying
and editing the value of a SpinnerListModel
with a JFormattedTextField
. This
ListEditor
becomes both a ChangeListener
on the spinner and a PropertyChangeListener
on the new JFormattedTextField
.
Params: - spinner – the spinner whose model
this
editor will monitor
Throws: - IllegalArgumentException – if the spinners model is not
an instance of
SpinnerListModel
See Also:
/**
* Construct a <code>JSpinner</code> editor that supports displaying
* and editing the value of a <code>SpinnerListModel</code>
* with a <code>JFormattedTextField</code>. <code>This</code>
* <code>ListEditor</code> becomes both a <code>ChangeListener</code>
* on the spinner and a <code>PropertyChangeListener</code>
* on the new <code>JFormattedTextField</code>.
*
* @param spinner the spinner whose model <code>this</code> editor will monitor
* @exception IllegalArgumentException if the spinners model is not
* an instance of <code>SpinnerListModel</code>
*
* @see #getModel
* @see SpinnerListModel
*/
public ListEditor(JSpinner spinner) {
super(spinner);
if (!(spinner.getModel() instanceof SpinnerListModel)) {
throw new IllegalArgumentException("model not a SpinnerListModel");
}
getTextField().setEditable(true);
getTextField().setFormatterFactory(new
DefaultFormatterFactory(new ListFormatter()));
}
Return our spinner ancestor's SpinnerNumberModel
.
See Also: Returns: getSpinner().getModel()
/**
* Return our spinner ancestor's <code>SpinnerNumberModel</code>.
*
* @return <code>getSpinner().getModel()</code>
* @see #getSpinner
* @see #getTextField
*/
public SpinnerListModel getModel() {
return (SpinnerListModel)(getSpinner().getModel());
}
ListFormatter provides completion while text is being input
into the JFormattedTextField. Completion is only done if the
user is inserting text at the end of the document. Completion
is done by way of the SpinnerListModel method findNextMatch.
/**
* ListFormatter provides completion while text is being input
* into the JFormattedTextField. Completion is only done if the
* user is inserting text at the end of the document. Completion
* is done by way of the SpinnerListModel method findNextMatch.
*/
private class ListFormatter extends
JFormattedTextField.AbstractFormatter {
private DocumentFilter filter;
public String valueToString(Object value) throws ParseException {
if (value == null) {
return "";
}
return value.toString();
}
public Object stringToValue(String string) throws ParseException {
return string;
}
protected DocumentFilter getDocumentFilter() {
if (filter == null) {
filter = new Filter();
}
return filter;
}
private class Filter extends DocumentFilter {
public void replace(FilterBypass fb, int offset, int length,
String string, AttributeSet attrs) throws
BadLocationException {
if (string != null && (offset + length) ==
fb.getDocument().getLength()) {
Object next = getModel().findNextMatch(
fb.getDocument().getText(0, offset) +
string);
String value = (next != null) ? next.toString() : null;
if (value != null) {
fb.remove(0, offset + length);
fb.insertString(0, value, null);
getFormattedTextField().select(offset +
string.length(),
value.length());
return;
}
}
super.replace(fb, offset, length, string, attrs);
}
public void insertString(FilterBypass fb, int offset,
String string, AttributeSet attr)
throws BadLocationException {
replace(fb, offset, 0, string, attr);
}
}
}
}
An Action implementation that is always disabled.
/**
* An Action implementation that is always disabled.
*/
private static class DisabledAction implements Action {
public Object getValue(String key) {
return null;
}
public void putValue(String key, Object value) {
}
public void setEnabled(boolean b) {
}
public boolean isEnabled() {
return false;
}
public void addPropertyChangeListener(PropertyChangeListener l) {
}
public void removePropertyChangeListener(PropertyChangeListener l) {
}
public void actionPerformed(ActionEvent ae) {
}
}
/////////////////
// Accessibility support
////////////////
Gets the AccessibleContext
for the JSpinner
Returns: the AccessibleContext
for the JSpinner
Since: 1.5
/**
* Gets the <code>AccessibleContext</code> for the <code>JSpinner</code>
*
* @return the <code>AccessibleContext</code> for the <code>JSpinner</code>
* @since 1.5
*/
@BeanProperty(bound = false)
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJSpinner();
}
return accessibleContext;
}
AccessibleJSpinner
implements accessibility
support for the JSpinner
class.
Since: 1.5
/**
* <code>AccessibleJSpinner</code> implements accessibility
* support for the <code>JSpinner</code> class.
* @since 1.5
*/
protected class AccessibleJSpinner extends AccessibleJComponent
implements AccessibleValue, AccessibleAction, AccessibleText,
AccessibleEditableText, ChangeListener {
private Object oldModelValue = null;
AccessibleJSpinner constructor
/**
* AccessibleJSpinner constructor
*/
protected AccessibleJSpinner() {
// model is guaranteed to be non-null
oldModelValue = model.getValue();
JSpinner.this.addChangeListener(this);
}
Invoked when the target of the listener has changed its state.
Params: - e – a
ChangeEvent
object. Must not be null.
Throws: - NullPointerException – if the parameter is null.
/**
* Invoked when the target of the listener has changed its state.
*
* @param e a <code>ChangeEvent</code> object. Must not be null.
* @throws NullPointerException if the parameter is null.
*/
public void stateChanged(ChangeEvent e) {
if (e == null) {
throw new NullPointerException();
}
Object newModelValue = model.getValue();
firePropertyChange(ACCESSIBLE_VALUE_PROPERTY,
oldModelValue,
newModelValue);
firePropertyChange(ACCESSIBLE_TEXT_PROPERTY,
null,
0); // entire text may have changed
oldModelValue = newModelValue;
}
/* ===== Begin AccessibleContext methods ===== */
Gets the role of this object. The role of the object is the generic
purpose or use of the class of this object. For example, the role
of a push button is AccessibleRole.PUSH_BUTTON. The roles in
AccessibleRole are provided so component developers can pick from
a set of predefined roles. This enables assistive technologies to
provide a consistent interface to various tweaked subclasses of
components (e.g., use AccessibleRole.PUSH_BUTTON for all components
that act like a push button) as well as distinguish between subclasses
that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
and AccessibleRole.RADIO_BUTTON for radio buttons).
Note that the AccessibleRole class is also extensible, so
custom component developers can define their own AccessibleRole's
if the set of predefined roles is inadequate.
See Also: Returns: an instance of AccessibleRole describing the role of the object
/**
* Gets the role of this object. The role of the object is the generic
* purpose or use of the class of this object. For example, the role
* of a push button is AccessibleRole.PUSH_BUTTON. The roles in
* AccessibleRole are provided so component developers can pick from
* a set of predefined roles. This enables assistive technologies to
* provide a consistent interface to various tweaked subclasses of
* components (e.g., use AccessibleRole.PUSH_BUTTON for all components
* that act like a push button) as well as distinguish between subclasses
* that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
* and AccessibleRole.RADIO_BUTTON for radio buttons).
* <p>Note that the AccessibleRole class is also extensible, so
* custom component developers can define their own AccessibleRole's
* if the set of predefined roles is inadequate.
*
* @return an instance of AccessibleRole describing the role of the object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.SPIN_BOX;
}
Returns the number of accessible children of the object.
Returns: the number of accessible children of the object.
/**
* Returns the number of accessible children of the object.
*
* @return the number of accessible children of the object.
*/
public int getAccessibleChildrenCount() {
// the JSpinner has one child, the editor
if (editor.getAccessibleContext() != null) {
return 1;
}
return 0;
}
Returns the specified Accessible child of the object. The Accessible
children of an Accessible object are zero-based, so the first child
of an Accessible child is at index 0, the second child is at index 1,
and so on.
Params: - i – zero-based index of child
See Also: Returns: the Accessible child of the object
/**
* Returns the specified Accessible child of the object. The Accessible
* children of an Accessible object are zero-based, so the first child
* of an Accessible child is at index 0, the second child is at index 1,
* and so on.
*
* @param i zero-based index of child
* @return the Accessible child of the object
* @see #getAccessibleChildrenCount
*/
public Accessible getAccessibleChild(int i) {
// the JSpinner has one child, the editor
if (i != 0) {
return null;
}
if (editor.getAccessibleContext() != null) {
return (Accessible)editor;
}
return null;
}
/* ===== End AccessibleContext methods ===== */
Gets the AccessibleAction associated with this object that supports
one or more actions.
See Also: Returns: AccessibleAction if supported by object; else return null
/**
* Gets the AccessibleAction associated with this object that supports
* one or more actions.
*
* @return AccessibleAction if supported by object; else return null
* @see AccessibleAction
*/
public AccessibleAction getAccessibleAction() {
return this;
}
Gets the AccessibleText associated with this object presenting
text on the display.
See Also: Returns: AccessibleText if supported by object; else return null
/**
* Gets the AccessibleText associated with this object presenting
* text on the display.
*
* @return AccessibleText if supported by object; else return null
* @see AccessibleText
*/
public AccessibleText getAccessibleText() {
return this;
}
/*
* Returns the AccessibleContext for the JSpinner editor
*/
private AccessibleContext getEditorAccessibleContext() {
if (editor instanceof DefaultEditor) {
JTextField textField = ((DefaultEditor)editor).getTextField();
if (textField != null) {
return textField.getAccessibleContext();
}
} else if (editor instanceof Accessible) {
return editor.getAccessibleContext();
}
return null;
}
/*
* Returns the AccessibleText for the JSpinner editor
*/
private AccessibleText getEditorAccessibleText() {
AccessibleContext ac = getEditorAccessibleContext();
if (ac != null) {
return ac.getAccessibleText();
}
return null;
}
/*
* Returns the AccessibleEditableText for the JSpinner editor
*/
private AccessibleEditableText getEditorAccessibleEditableText() {
AccessibleText at = getEditorAccessibleText();
if (at instanceof AccessibleEditableText) {
return (AccessibleEditableText)at;
}
return null;
}
Gets the AccessibleValue associated with this object.
See Also: Returns: AccessibleValue if supported by object; else return null
/**
* Gets the AccessibleValue associated with this object.
*
* @return AccessibleValue if supported by object; else return null
* @see AccessibleValue
*
*/
public AccessibleValue getAccessibleValue() {
return this;
}
/* ===== Begin AccessibleValue impl ===== */
Get the value of this object as a Number. If the value has not been
set, the return value will be null.
See Also: Returns: value of the object
/**
* Get the value of this object as a Number. If the value has not been
* set, the return value will be null.
*
* @return value of the object
* @see #setCurrentAccessibleValue
*/
public Number getCurrentAccessibleValue() {
Object o = model.getValue();
if (o instanceof Number) {
return (Number)o;
}
return null;
}
Set the value of this object as a Number.
Params: - n – the value to set for this object
See Also: Returns: true if the value was set; else False
/**
* Set the value of this object as a Number.
*
* @param n the value to set for this object
* @return true if the value was set; else False
* @see #getCurrentAccessibleValue
*/
public boolean setCurrentAccessibleValue(Number n) {
// try to set the new value
try {
model.setValue(n);
return true;
} catch (IllegalArgumentException iae) {
// SpinnerModel didn't like new value
}
return false;
}
Get the minimum value of this object as a Number.
See Also: Returns: Minimum value of the object; null if this object does not
have a minimum value
/**
* Get the minimum value of this object as a Number.
*
* @return Minimum value of the object; null if this object does not
* have a minimum value
* @see #getMaximumAccessibleValue
*/
public Number getMinimumAccessibleValue() {
if (model instanceof SpinnerNumberModel) {
SpinnerNumberModel numberModel = (SpinnerNumberModel)model;
Object o = numberModel.getMinimum();
if (o instanceof Number) {
return (Number)o;
}
}
return null;
}
Get the maximum value of this object as a Number.
See Also: Returns: Maximum value of the object; null if this object does not
have a maximum value
/**
* Get the maximum value of this object as a Number.
*
* @return Maximum value of the object; null if this object does not
* have a maximum value
* @see #getMinimumAccessibleValue
*/
public Number getMaximumAccessibleValue() {
if (model instanceof SpinnerNumberModel) {
SpinnerNumberModel numberModel = (SpinnerNumberModel)model;
Object o = numberModel.getMaximum();
if (o instanceof Number) {
return (Number)o;
}
}
return null;
}
/* ===== End AccessibleValue impl ===== */
/* ===== Begin AccessibleAction impl ===== */
Returns the number of accessible actions available in this object
If there are more than one, the first one is considered the "default"
action of the object.
Two actions are supported: AccessibleAction.INCREMENT which
increments the spinner value and AccessibleAction.DECREMENT
which decrements the spinner value
Returns: the zero-based number of Actions in this object
/**
* Returns the number of accessible actions available in this object
* If there are more than one, the first one is considered the "default"
* action of the object.
*
* Two actions are supported: AccessibleAction.INCREMENT which
* increments the spinner value and AccessibleAction.DECREMENT
* which decrements the spinner value
*
* @return the zero-based number of Actions in this object
*/
public int getAccessibleActionCount() {
return 2;
}
Returns a description of the specified action of the object.
Params: - i – zero-based index of the actions
See Also: Returns: a String description of the action
/**
* Returns a description of the specified action of the object.
*
* @param i zero-based index of the actions
* @return a String description of the action
* @see #getAccessibleActionCount
*/
public String getAccessibleActionDescription(int i) {
if (i == 0) {
return AccessibleAction.INCREMENT;
} else if (i == 1) {
return AccessibleAction.DECREMENT;
}
return null;
}
Performs the specified Action on the object
Params: - i – zero-based index of actions. The first action
(index 0) is AccessibleAction.INCREMENT and the second
action (index 1) is AccessibleAction.DECREMENT.
See Also: Returns: true if the action was performed; otherwise false.
/**
* Performs the specified Action on the object
*
* @param i zero-based index of actions. The first action
* (index 0) is AccessibleAction.INCREMENT and the second
* action (index 1) is AccessibleAction.DECREMENT.
* @return true if the action was performed; otherwise false.
* @see #getAccessibleActionCount
*/
public boolean doAccessibleAction(int i) {
if (i < 0 || i > 1) {
return false;
}
Object o;
if (i == 0) {
o = getNextValue(); // AccessibleAction.INCREMENT
} else {
o = getPreviousValue(); // AccessibleAction.DECREMENT
}
// try to set the new value
try {
model.setValue(o);
return true;
} catch (IllegalArgumentException iae) {
// SpinnerModel didn't like new value
}
return false;
}
/* ===== End AccessibleAction impl ===== */
/* ===== Begin AccessibleText impl ===== */
/*
* Returns whether source and destination components have the
* same window ancestor
*/
private boolean sameWindowAncestor(Component src, Component dest) {
if (src == null || dest == null) {
return false;
}
return SwingUtilities.getWindowAncestor(src) ==
SwingUtilities.getWindowAncestor(dest);
}
Given a point in local coordinates, return the zero-based index
of the character under that Point. If the point is invalid,
this method returns -1.
Params: - p – the Point in local coordinates
Returns: the zero-based index of the character under Point p; if
Point is invalid return -1.
/**
* Given a point in local coordinates, return the zero-based index
* of the character under that Point. If the point is invalid,
* this method returns -1.
*
* @param p the Point in local coordinates
* @return the zero-based index of the character under Point p; if
* Point is invalid return -1.
*/
public int getIndexAtPoint(Point p) {
AccessibleText at = getEditorAccessibleText();
if (at != null && sameWindowAncestor(JSpinner.this, editor)) {
// convert point from the JSpinner bounds (source) to
// editor bounds (destination)
Point editorPoint = SwingUtilities.convertPoint(JSpinner.this,
p,
editor);
if (editorPoint != null) {
return at.getIndexAtPoint(editorPoint);
}
}
return -1;
}
Determines the bounding box of the character at the given
index into the string. The bounds are returned in local
coordinates. If the index is invalid an empty rectangle is
returned.
Params: - i – the index into the String
Returns: the screen coordinates of the character's bounding box,
if index is invalid return an empty rectangle.
/**
* Determines the bounding box of the character at the given
* index into the string. The bounds are returned in local
* coordinates. If the index is invalid an empty rectangle is
* returned.
*
* @param i the index into the String
* @return the screen coordinates of the character's bounding box,
* if index is invalid return an empty rectangle.
*/
public Rectangle getCharacterBounds(int i) {
AccessibleText at = getEditorAccessibleText();
if (at != null ) {
Rectangle editorRect = at.getCharacterBounds(i);
if (editorRect != null &&
sameWindowAncestor(JSpinner.this, editor)) {
// return rectangle in the JSpinner bounds
return SwingUtilities.convertRectangle(editor,
editorRect,
JSpinner.this);
}
}
return null;
}
Returns the number of characters (valid indicies)
Returns: the number of characters
/**
* Returns the number of characters (valid indicies)
*
* @return the number of characters
*/
public int getCharCount() {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getCharCount();
}
return -1;
}
Returns the zero-based offset of the caret.
Note: That to the right of the caret will have the same index
value as the offset (the caret is between two characters).
Returns: the zero-based offset of the caret.
/**
* Returns the zero-based offset of the caret.
*
* Note: That to the right of the caret will have the same index
* value as the offset (the caret is between two characters).
* @return the zero-based offset of the caret.
*/
public int getCaretPosition() {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getCaretPosition();
}
return -1;
}
Returns the String at a given index.
Params: - part – the CHARACTER, WORD, or SENTENCE to retrieve
- index – an index within the text
Returns: the letter, word, or sentence
/**
* Returns the String at a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public String getAtIndex(int part, int index) {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getAtIndex(part, index);
}
return null;
}
Returns the String after a given index.
Params: - part – the CHARACTER, WORD, or SENTENCE to retrieve
- index – an index within the text
Returns: the letter, word, or sentence
/**
* Returns the String after a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public String getAfterIndex(int part, int index) {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getAfterIndex(part, index);
}
return null;
}
Returns the String before a given index.
Params: - part – the CHARACTER, WORD, or SENTENCE to retrieve
- index – an index within the text
Returns: the letter, word, or sentence
/**
* Returns the String before a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public String getBeforeIndex(int part, int index) {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getBeforeIndex(part, index);
}
return null;
}
Returns the AttributeSet for a given character at a given index
Params: - i – the zero-based index into the text
Returns: the AttributeSet of the character
/**
* Returns the AttributeSet for a given character at a given index
*
* @param i the zero-based index into the text
* @return the AttributeSet of the character
*/
public AttributeSet getCharacterAttribute(int i) {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getCharacterAttribute(i);
}
return null;
}
Returns the start offset within the selected text.
If there is no selection, but there is
a caret, the start and end offsets will be the same.
Returns: the index into the text of the start of the selection
/**
* Returns the start offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into the text of the start of the selection
*/
public int getSelectionStart() {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getSelectionStart();
}
return -1;
}
Returns the end offset within the selected text.
If there is no selection, but there is
a caret, the start and end offsets will be the same.
Returns: the index into the text of the end of the selection
/**
* Returns the end offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into the text of the end of the selection
*/
public int getSelectionEnd() {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getSelectionEnd();
}
return -1;
}
Returns the portion of the text that is selected.
Returns: the String portion of the text that is selected
/**
* Returns the portion of the text that is selected.
*
* @return the String portion of the text that is selected
*/
public String getSelectedText() {
AccessibleText at = getEditorAccessibleText();
if (at != null) {
return at.getSelectedText();
}
return null;
}
/* ===== End AccessibleText impl ===== */
/* ===== Begin AccessibleEditableText impl ===== */
Sets the text contents to the specified string.
Params: - s – the string to set the text contents
/**
* Sets the text contents to the specified string.
*
* @param s the string to set the text contents
*/
public void setTextContents(String s) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.setTextContents(s);
}
}
Inserts the specified string at the given index/
Params: - index – the index in the text where the string will
be inserted
- s – the string to insert in the text
/**
* Inserts the specified string at the given index/
*
* @param index the index in the text where the string will
* be inserted
* @param s the string to insert in the text
*/
public void insertTextAtIndex(int index, String s) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.insertTextAtIndex(index, s);
}
}
Returns the text string between two indices.
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
Returns: the text string between the indices
/**
* Returns the text string between two indices.
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
* @return the text string between the indices
*/
public String getTextRange(int startIndex, int endIndex) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
return at.getTextRange(startIndex, endIndex);
}
return null;
}
Deletes the text between two indices
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
/**
* Deletes the text between two indices
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
*/
public void delete(int startIndex, int endIndex) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.delete(startIndex, endIndex);
}
}
Cuts the text between two indices into the system clipboard.
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
/**
* Cuts the text between two indices into the system clipboard.
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
*/
public void cut(int startIndex, int endIndex) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.cut(startIndex, endIndex);
}
}
Pastes the text from the system clipboard into the text
starting at the specified index.
Params: - startIndex – the starting index in the text
/**
* Pastes the text from the system clipboard into the text
* starting at the specified index.
*
* @param startIndex the starting index in the text
*/
public void paste(int startIndex) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.paste(startIndex);
}
}
Replaces the text between two indices with the specified
string.
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
- s – the string to replace the text between two indices
/**
* Replaces the text between two indices with the specified
* string.
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
* @param s the string to replace the text between two indices
*/
public void replaceText(int startIndex, int endIndex, String s) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.replaceText(startIndex, endIndex, s);
}
}
Selects the text between two indices.
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
/**
* Selects the text between two indices.
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
*/
public void selectText(int startIndex, int endIndex) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.selectText(startIndex, endIndex);
}
}
Sets attributes for the text between two indices.
Params: - startIndex – the starting index in the text
- endIndex – the ending index in the text
- as – the attribute set
See Also:
/**
* Sets attributes for the text between two indices.
*
* @param startIndex the starting index in the text
* @param endIndex the ending index in the text
* @param as the attribute set
* @see AttributeSet
*/
public void setAttributes(int startIndex, int endIndex, AttributeSet as) {
AccessibleEditableText at = getEditorAccessibleEditableText();
if (at != null) {
at.setAttributes(startIndex, endIndex, as);
}
}
} /* End AccessibleJSpinner */
}