FileDocCategorySizeDatePackage
JFormattedTextField.javaAPI DocJava SE 5 API42737Fri Aug 26 14:57:54 BST 2005javax.swing

JFormattedTextField

public class JFormattedTextField extends JTextField
JFormattedTextField extends JTextField adding support for formatting arbitrary values, as well as retrieving a particular object once the user has edited the text. The following illustrates configuring a JFormattedTextField to edit dates:
JFormattedTextField ftf = new JFormattedTextField();
ftf.setValue(new Date());

Once a JFormattedTextField has been created, you can listen for editing changes by way of adding a PropertyChangeListener and listening for PropertyChangeEvents with the property name value.

JFormattedTextField allows configuring what action should be taken when focus is lost. The possible configurations are:

Value

Description

JFormattedTextField.REVERT Revert the display to match that of getValue, possibly losing the current edit.
JFormattedTextField.COMMIT Commits the current value. If the value being edited isn't considered a legal value by the AbstractFormatter that is, a ParseException is thrown, then the value will not change, and then edited value will persist.
JFormattedTextField.COMMIT_OR_REVERT Similar to COMMIT, but if the value isn't legal, behave like REVERT.
JFormattedTextField.PERSIST Do nothing, don't obtain a new AbstractFormatter, and don't update the value.
The default is JFormattedTextField.COMMIT_OR_REVERT, refer to {@link #setFocusLostBehavior} for more information on this.

JFormattedTextField allows the focus to leave, even if the currently edited value is invalid. To lock the focus down while the JFormattedTextField is an invalid edit state you can attach an InputVerifier. The following code snippet shows a potential implementation of such an InputVerifier:

public class FormattedTextFieldVerifier extends InputVerifier {
public boolean verify(JComponent input) {
if (input instanceof JFormattedTextField) {
JFormattedTextField ftf = (JFormattedTextField)input;
AbstractFormatter formatter = ftf.getFormatter();
if (formatter != null) {
String text = ftf.getText();
try {
formatter.stringToValue(text);
return true;
} catch (ParseException pe) {
return false;
}
}
}
return true;
}
public boolean shouldYieldFocus(JComponent input) {
return verify(input);
}
}

Alternatively, you could invoke commitEdit, which would also commit the value.

JFormattedTextField does not do the formatting it self, rather formatting is done through an instance of JFormattedTextField.AbstractFormatter which is obtained from an instance of JFormattedTextField.AbstractFormatterFactory. Instances of JFormattedTextField.AbstractFormatter are notified when they become active by way of the install method, at which point the JFormattedTextField.AbstractFormatter can install whatever it needs to, typically a DocumentFilter. Similarly when JFormattedTextField no longer needs the AbstractFormatter, it will invoke uninstall.

JFormattedTextField typically queries the AbstractFormatterFactory for an AbstractFormat when it gains or loses focus. Although this can change based on the focus lost policy. If the focus lost policy is JFormattedTextField.PERSIST and the JFormattedTextField has been edited, the AbstractFormatterFactory will not be queried until the value has been commited. Similarly if the focus lost policy is JFormattedTextField.COMMIT and an exception is thrown from stringToValue, the AbstractFormatterFactory will not be querired when focus is lost or gained.

JFormattedTextField.AbstractFormatter is also responsible for determining when values are commited to the JFormattedTextField. Some JFormattedTextField.AbstractFormatters will make new values available on every edit, and others will never commit the value. You can force the current value to be obtained from the current JFormattedTextField.AbstractFormatter by way of invoking commitEdit. commitEdit will be invoked whenever return is pressed in the JFormattedTextField.

If an AbstractFormatterFactory has not been explicitly set, one will be set based on the Class of the value type after setValue has been invoked (assuming value is non-null). For example, in the following code an appropriate AbstractFormatterFactory and AbstractFormatter will be created to handle formatting of numbers:

JFormattedTextField tf = new JFormattedTextField();
tf.setValue(new Number(100));

Warning: As the AbstractFormatter will typically install a DocumentFilter on the Document, and a NavigationFilter on the JFormattedTextField you should not install your own. If you do, you are likely to see odd behavior in that the editing policy of the AbstractFormatter will not be enforced.

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 JavaBeansTM has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}.

version
1.22 12/19/03
since
1.4

Fields Summary
private static final String
uiClassID
private static final Action[]
defaultActions
public static final int
COMMIT
Constant identifying that when focus is lost, commitEdit should be invoked. If in commiting the new value a ParseException is thrown, the invalid value will remain.
public static final int
COMMIT_OR_REVERT
Constant identifying that when focus is lost, commitEdit should be invoked. If in commiting the new value a ParseException is thrown, the value will be reverted.
public static final int
REVERT
Constant identifying that when focus is lost, editing value should be reverted to current value set on the JFormattedTextField.
public static final int
PERSIST
Constant identifying that when focus is lost, the edited value should be left.
private AbstractFormatterFactory
factory
Factory used to obtain an instance of AbstractFormatter.
private AbstractFormatter
format
Object responsible for formatting the current value.
private Object
value
Last valid value.
private boolean
editValid
True while the value being edited is valid.
private int
focusLostBehavior
Behavior when focus is lost.
private boolean
edited
Indicates the current value has been edited.
private DocumentListener
documentListener
Used to set the dirty state.
private Object
mask
Masked used to set the AbstractFormatterFactory.
private ActionMap
textFormatterActionMap
ActionMap that the TextFormatter Actions are added to.
private boolean
composedTextExists
Indicates the input method composed text is in the document
private FocusLostHandler
focusLostHandler
A handler for FOCUS_LOST event
Constructors Summary
public JFormattedTextField()
Creates a JFormattedTextField with no AbstractFormatterFactory. Use setMask or setFormatterFactory to configure the JFormattedTextField to edit a particular type of value.



                              
      
        super();
        enableEvents(AWTEvent.FOCUS_EVENT_MASK);
        setFocusLostBehavior(COMMIT_OR_REVERT);
    
public JFormattedTextField(Object value)
Creates a JFormattedTextField with the specified value. This will create an AbstractFormatterFactory based on the type of value.

param
value Initial value for the JFormattedTextField

        this();
        setValue(value);
    
public JFormattedTextField(Format format)
Creates a JFormattedTextField. format is wrapped in an appropriate AbstractFormatter which is then wrapped in an AbstractFormatterFactory.

param
format Format used to look up an AbstractFormatter

        this();
        setFormatterFactory(getDefaultFormatterFactory(format));
    
public JFormattedTextField(AbstractFormatter formatter)
Creates a JFormattedTextField with the specified AbstractFormatter. The AbstractFormatter is placed in an AbstractFormatterFactory.

param
formatter AbstractFormatter to use for formatting.

        this(new DefaultFormatterFactory(formatter));
    
public JFormattedTextField(AbstractFormatterFactory factory)
Creates a JFormattedTextField with the specified AbstractFormatterFactory.

param
factory AbstractFormatterFactory used for formatting.

        this();
        setFormatterFactory(factory);
    
public JFormattedTextField(AbstractFormatterFactory factory, Object currentValue)
Creates a JFormattedTextField with the specified AbstractFormatterFactory and initial value.

param
factory AbstractFormatterFactory used for formatting.
param
currentValue Initial value to use

        this(currentValue);
        setFormatterFactory(factory);
    
Methods Summary
public voidcommitEdit()
Forces the current value to be taken from the AbstractFormatter and set as the current value. This has no effect if there is no current AbstractFormatter installed.

throws
ParseException if the AbstractFormatter is not able to format the current value

        AbstractFormatter format = getFormatter();

        if (format != null) {
            setValue(format.stringToValue(getText()), false, true);
        }
    
public javax.swing.Action[]getActions()
Fetches the command list for the editor. This is the list of commands supported by the plugged-in UI augmented by the collection of commands that the editor itself supports. These are useful for binding to events, such as in a keymap.

return
the command list

        return TextAction.augmentList(super.getActions(), defaultActions);
    
private javax.swing.JFormattedTextField$AbstractFormatterFactorygetDefaultFormatterFactory(java.lang.Object type)
Returns an AbstractFormatterFactory suitable for the passed in Object type.

        if (type instanceof DateFormat) {
            return new DefaultFormatterFactory(new DateFormatter
                                               ((DateFormat)type));
        }
        if (type instanceof NumberFormat) {
            return new DefaultFormatterFactory(new NumberFormatter(
                                               (NumberFormat)type));
        }
        if (type instanceof Format) {
            return new DefaultFormatterFactory(new InternationalFormatter(
                                               (Format)type));
        }
        if (type instanceof Date) {
            return new DefaultFormatterFactory(new DateFormatter());
        }
        if (type instanceof Number) {
            AbstractFormatter displayFormatter = new NumberFormatter();
	    ((NumberFormatter)displayFormatter).setValueClass(type.getClass());
            AbstractFormatter editFormatter = new NumberFormatter(
                                  new DecimalFormat("#.#"));
	    ((NumberFormatter)editFormatter).setValueClass(type.getClass());

            return new DefaultFormatterFactory(displayFormatter,
                                               displayFormatter,editFormatter);
        }
        return new DefaultFormatterFactory(new DefaultFormatter());
    
public intgetFocusLostBehavior()
Returns the behavior when focus is lost. This will be one of COMMIT_OR_REVERT, COMMIT, REVERT or PERSIST Note that some AbstractFormatters may push changes as they occur, so that the value of this will have no effect.

return
returns behavior when focus is lost

        return focusLostBehavior;
    
public javax.swing.JFormattedTextField$AbstractFormattergetFormatter()
Returns the AbstractFormatter that is used to format and parse the current value.

return
AbstractFormatter used for formatting

        return format;
    
public javax.swing.JFormattedTextField$AbstractFormatterFactorygetFormatterFactory()
Returns the current AbstractFormatterFactory.

see
#setFormatterFactory
return
AbstractFormatterFactory used to determine AbstractFormatters

        return factory;
    
public java.lang.StringgetUIClassID()
Gets the class ID for a UI.

return
the string "FormattedTextFieldUI"
see
JComponent#getUIClassID

        return uiClassID;
    
public java.lang.ObjectgetValue()
Returns the last valid value. Based on the editing policy of the AbstractFormatter this may not return the current value. The currently edited value can be obtained by invoking commitEdit followed by getValue.

return
Last valid value

        return value;
    
protected voidinvalidEdit()
Invoked when the user inputs an invalid value. This gives the component a chance to provide feedback. The default implementation beeps.

	UIManager.getLookAndFeel().provideErrorFeedback(JFormattedTextField.this);
    
public booleanisEditValid()
Returns true if the current value being edited is valid. The value of this is managed by the current AbstractFormatter, as such there is no public setter for it.

return
true if the current value being edited is valid.

        return editValid;
    
private booleanisEdited()
Returns true if the receiver has been edited.

        return edited;
    
protected voidprocessFocusEvent(java.awt.event.FocusEvent e)
Processes any focus events, such as FocusEvent.FOCUS_GAINED or FocusEvent.FOCUS_LOST.

param
e the FocusEvent
see
FocusEvent

        super.processFocusEvent(e);

	// ignore temporary focus event
	if (e.isTemporary()) {
	    return;
	}

        if (isEdited() && e.getID() == FocusEvent.FOCUS_LOST) {
	    InputContext ic = getInputContext();
	    if (focusLostHandler == null) {
		focusLostHandler = new FocusLostHandler();
	    }
	    
	    // if there is a composed text, process it first
	    if ((ic != null) && composedTextExists) {
		ic.endComposition();
		EventQueue.invokeLater(focusLostHandler);
	    } else {
		focusLostHandler.run();
	    }
        }
        else if (!isEdited()) {
            // reformat
            setValue(getValue(), true, true);
        }
    
protected voidprocessInputMethodEvent(java.awt.event.InputMethodEvent e)
Processes any input method events, such as InputMethodEvent.INPUT_METHOD_TEXT_CHANGED or InputMethodEvent.CARET_POSITION_CHANGED.

param
e the InputMethodEvent
see
InputMethodEvent

	AttributedCharacterIterator text = e.getText();
	int commitCount = e.getCommittedCharacterCount();

	// Keep track of the composed text
	if (text != null) {
	    int begin = text.getBeginIndex();
	    int end = text.getEndIndex();
	    composedTextExists = ((end - begin) > commitCount);
	} else {
	    composedTextExists = false;
	}

	super.processInputMethodEvent(e);
    
public voidsetDocument(javax.swing.text.Document doc)
Associates the editor with a text document. The currently registered factory is used to build a view for the document, which gets displayed by the editor after revalidation. A PropertyChange event ("document") is propagated to each listener.

param
doc the document to display/edit
see
#getDocument
beaninfo
description: the text document model bound: true expert: true

        if (documentListener != null && getDocument() != null) {
            getDocument().removeDocumentListener(documentListener);
        }
        super.setDocument(doc);
        if (documentListener == null) {
            documentListener = new DocumentHandler();
        }
        doc.addDocumentListener(documentListener);
    
private voidsetEditValid(boolean isValid)
Sets the validity of the edit on the receiver. You should not normally invoke this. This will be invoked by the AbstractFormatter as the user edits the value.

Not all formatters will allow the component to get into an invalid state, and thus this may never be invoked.

Based on the look and feel this may visually change the state of the receiver.

param
isValid boolean indicating if the currently edited value is valid.
beaninfo
bound: true attribute: visualUpdate true description: True indicates the edited value is valid

        if (isValid != editValid) {
            editValid = isValid;
            firePropertyChange("editValid", Boolean.valueOf(!isValid),
                               Boolean.valueOf(isValid));
        }
    
private voidsetEdited(boolean edited)
Sets the edited state of the receiver.

        this.edited = edited;
    
public voidsetFocusLostBehavior(int behavior)
Sets the behavior when focus is lost. This will be one of JFormattedTextField.COMMIT_OR_REVERT, JFormattedTextField.REVERT, JFormattedTextField.COMMIT or JFormattedTextField.PERSIST Note that some AbstractFormatters may push changes as they occur, so that the value of this will have no effect.

This will throw an IllegalArgumentException if the object passed in is not one of the afore mentioned values.

The default value of this property is JFormattedTextField.COMMIT_OR_REVERT.

param
behavior Identifies behavior when focus is lost
throws
IllegalArgumentException if behavior is not one of the known values
beaninfo
enum: COMMIT JFormattedTextField.COMMIT COMMIT_OR_REVERT JFormattedTextField.COMMIT_OR_REVERT REVERT JFormattedTextField.REVERT PERSIST JFormattedTextField.PERSIST description: Behavior when component loses focus

        if (behavior != COMMIT && behavior != COMMIT_OR_REVERT &&
            behavior != PERSIST && behavior != REVERT) {
            throw new IllegalArgumentException("setFocusLostBehavior must be one of: JFormattedTextField.COMMIT, JFormattedTextField.COMMIT_OR_REVERT, JFormattedTextField.PERSIST or JFormattedTextField.REVERT");
        }
        focusLostBehavior = behavior;
    
protected voidsetFormatter(javax.swing.JFormattedTextField$AbstractFormatter format)
Sets the current AbstractFormatter.

You should not normally invoke this, instead set the AbstractFormatterFactory or set the value. JFormattedTextField will invoke this as the state of the JFormattedTextField changes and requires the value to be reset. JFormattedTextField passes in the AbstractFormatter obtained from the AbstractFormatterFactory.

This is a JavaBeans bound property.

see
#setFormatterFactory
param
format AbstractFormatter to use for formatting
beaninfo
bound: true attribute: visualUpdate true description: TextFormatter, responsible for formatting the current value

        AbstractFormatter oldFormat = this.format;

        if (oldFormat != null) {
            oldFormat.uninstall();
        }
        setEditValid(true);
        this.format = format;
        if (format != null) {
            format.install(this);
        }
        setEdited(false);
        firePropertyChange("textFormatter", oldFormat, format);
    
private voidsetFormatterActions(javax.swing.Action[] actions)
Resets the Actions that come from the TextFormatter to actions.

        if (actions == null) {
            if (textFormatterActionMap != null) {
                textFormatterActionMap.clear();
            }
        }
        else {
            if (textFormatterActionMap == null) {
                ActionMap map = getActionMap();

                textFormatterActionMap = new ActionMap();
                while (map != null) {
                    ActionMap parent = map.getParent();

                    if (parent instanceof UIResource || parent == null) {
                        map.setParent(textFormatterActionMap);
                        textFormatterActionMap.setParent(parent);
                        break;
                    }
                    map = parent;
                }
            }
            for (int counter = actions.length - 1; counter >= 0;
                 counter--) {
                Object key = actions[counter].getValue(Action.NAME);

                if (key != null) {
                    textFormatterActionMap.put(key, actions[counter]);
                }
            }
        }
    
public voidsetFormatterFactory(javax.swing.JFormattedTextField$AbstractFormatterFactory tf)
Sets the AbstractFormatterFactory. AbstractFormatterFactory is able to return an instance of AbstractFormatter that is used to format a value for display, as well an enforcing an editing policy.

If you have not explicitly set an AbstractFormatterFactory by way of this method (or a constructor) an AbstractFormatterFactory and consequently an AbstractFormatter will be used based on the Class of the value. NumberFormatter will be used for Numbers, DateFormatter will be used for Dates, otherwise DefaultFormatter will be used.

This is a JavaBeans bound property.

param
tf AbstractFormatterFactory used to lookup instances of AbstractFormatter
beaninfo
bound: true attribute: visualUpdate true description: AbstractFormatterFactory, responsible for returning an AbstractFormatter that can format the current value.

        AbstractFormatterFactory oldFactory = factory;

        factory = tf;
        firePropertyChange("formatterFactory", oldFactory, tf);
        setValue(getValue(), true, false);
    
public voidsetValue(java.lang.Object value)
Sets the value that will be formatted by an AbstractFormatter obtained from the current AbstractFormatterFactory. If no AbstractFormatterFactory has been specified, this will attempt to create one based on the type of value.

The default value of this property is null.

This is a JavaBeans bound property.

param
value Current value to display
beaninfo
bound: true attribute: visualUpdate true description: The value to be formatted.

        if (value != null && getFormatterFactory() == null) {
            setFormatterFactory(getDefaultFormatterFactory(value));
        }
        setValue(value, true, true);
    
private voidsetValue(java.lang.Object value, boolean createFormat, boolean firePC)
Does the setting of the value. If createFormat is true, this will also obtain a new AbstractFormatter from the current factory. The property change event will be fired if firePC is true.

        Object oldValue = this.value;

        this.value = value;

        if (createFormat) {
            AbstractFormatterFactory factory = getFormatterFactory();
            AbstractFormatter atf;

            if (factory != null) {
                atf = factory.getFormatter(this);
            }
            else {
                atf = null;
            }
            setFormatter(atf);
        }
        else {
            // Assumed to be valid
            setEditValid(true);
        }

        setEdited(false);

	if (firePC) {
	    firePropertyChange("value", oldValue, value);
	}
    
private voidwriteObject(java.io.ObjectOutputStream s)

        s.defaultWriteObject();
        if (getUIClassID().equals(uiClassID)) {
            byte count = JComponent.getWriteObjCounter(this);
            JComponent.setWriteObjCounter(this, --count);
            if (count == 0 && ui != null) {
                ui.installUI(this);
            }
        }