From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- .../classpath/javax/swing/JFormattedTextField.java | 648 +++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 libjava/classpath/javax/swing/JFormattedTextField.java (limited to 'libjava/classpath/javax/swing/JFormattedTextField.java') diff --git a/libjava/classpath/javax/swing/JFormattedTextField.java b/libjava/classpath/javax/swing/JFormattedTextField.java new file mode 100644 index 000000000..e4b6fec79 --- /dev/null +++ b/libjava/classpath/javax/swing/JFormattedTextField.java @@ -0,0 +1,648 @@ +/* JFormattedTextField.java -- + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing; + +import java.awt.event.FocusEvent; +import java.io.Serializable; +import java.text.DateFormat; +import java.text.Format; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Date; + +import javax.swing.text.AbstractDocument; +import javax.swing.text.DateFormatter; +import javax.swing.text.DefaultFormatter; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.Document; +import javax.swing.text.DocumentFilter; +import javax.swing.text.InternationalFormatter; +import javax.swing.text.NavigationFilter; +import javax.swing.text.NumberFormatter; + +/** + * A text field that makes use of a formatter to display and edit a specific + * type of data. The value that is displayed can be an arbitrary object. The + * formatter is responsible for displaying the value in a textual form and + * it may allow editing of the value. + * + * Formatters are usually obtained using an instance of + * {@link AbstractFormatterFactory}. This factory is responsible for providing + * an instance of {@link AbstractFormatter} that is able to handle the + * formatting of the value of the JFormattedTextField. + * + * @author Michael Koch + * @author Anthony Balkissoon abalkiss at redhat dot com + * + * @since 1.4 + */ +public class JFormattedTextField extends JTextField +{ + private static final long serialVersionUID = 5464657870110180632L; + + /** + * An abstract base implementation for a formatter that can be used by + * a JTextField. A formatter can display a specific type of object and + * may provide a way to edit this value. + */ + public abstract static class AbstractFormatter implements Serializable + { + private static final long serialVersionUID = -5193212041738979680L; + + private JFormattedTextField textField; + + public AbstractFormatter () + { + //Do nothing here. + } + + /** + * Clones the AbstractFormatter and removes the association to any + * particular JFormattedTextField. + * + * @return a clone of this formatter with no association to any particular + * JFormattedTextField + * @throws CloneNotSupportedException if the Object's class doesn't support + * the {@link Cloneable} interface + */ + protected Object clone() + throws CloneNotSupportedException + { + // Clone this formatter. + AbstractFormatter newFormatter = (AbstractFormatter) super.clone(); + + // And remove the association to the JFormattedTextField. + newFormatter.textField = null; + return newFormatter; + } + + /** + * Returns a custom set of Actions that this formatter supports. Should + * be subclassed by formatters that have a custom set of Actions. + * + * @return null. Should be subclassed by formatters that want + * to install custom Actions on the JFormattedTextField. + */ + protected Action[] getActions() + { + return null; + } + + /** + * Gets the DocumentFilter for this formatter. Should be subclassed + * by formatters wishing to install a filter that oversees Document + * mutations. + * + * @return null. Should be subclassed by formatters + * that want to restrict Document mutations. + */ + protected DocumentFilter getDocumentFilter() + { + // Subclasses should override this if they want to install a + // DocumentFilter. + return null; + } + + /** + * Returns the JFormattedTextField on which this formatter is + * currently installed. + * + * @return the JFormattedTextField on which this formatter is currently + * installed + */ + protected JFormattedTextField getFormattedTextField() + { + return textField; + } + + /** + * Gets the NavigationFilter for this formatter. Should be subclassed + * by formatters (such as {@link DefaultFormatter}) that wish to + * restrict where the cursor can be placed within the text field. + * + * @return null. Subclassed by formatters that want to restrict + * cursor location within the JFormattedTextField. + */ + protected NavigationFilter getNavigationFilter() + { + // This should be subclassed if the formatter wants to install + // a NavigationFilter on the JFormattedTextField. + return null; + } + + /** + * Installs this formatter on the specified JFormattedTextField. This + * converts the current value to a displayable String and displays it, + * and installs formatter specific Actions from getActions. + * It also installs a DocumentFilter and NavigationFilter on the + * JFormattedTextField. + *

+ * If there is a ParseException this sets the text to an + * empty String and marks the text field in an invalid state. + * + * @param textField the JFormattedTextField on which to install this + * formatter + */ + public void install(JFormattedTextField textField) + { + // Uninstall the current textfield. + if (this.textField != null) + uninstall(); + + this.textField = textField; + + // Install some state on the text field, including display text, + // DocumentFilter, NavigationFilter, and formatter specific Actions. + if (textField != null) + { + try + { + // Set the text of the field. + textField.setText(valueToString(textField.getValue())); + Document doc = textField.getDocument(); + + // Set the DocumentFilter for the field's Document. + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).setDocumentFilter(getDocumentFilter()); + + // Set the NavigationFilter. + textField.setNavigationFilter(getNavigationFilter()); + + // Set the Formatter Actions + // FIXME: Have to add the actions from getActions() + } + catch (ParseException pe) + { + // Set the text to an empty String and mark the field as invalid. + textField.setText(""); + setEditValid(false); + } + } + } + + /** + * Clears the state installed on the JFormattedTextField by the formatter. + * This resets the DocumentFilter, NavigationFilter, and any additional + * Actions (returned by getActions()). + */ + public void uninstall() + { + // Set the DocumentFilter for the field's Document. + Document doc = textField.getDocument(); + if (doc instanceof AbstractDocument) + ((AbstractDocument) doc).setDocumentFilter(null); + textField.setNavigationFilter(null); + // FIXME: Have to remove the Actions from getActions() + this.textField = null; + } + + /** + * Invoke this method when invalid values are entered. This forwards the + * call to the JFormattedTextField. + */ + protected void invalidEdit() + { + textField.invalidEdit(); + } + + /** + * This method updates the editValid property of + * JFormattedTextField. + * + * @param valid the new state for the editValid property + */ + protected void setEditValid(boolean valid) + { + textField.editValid = valid; + } + + /** + * Parses text to return a corresponding Object. + * + * @param text the String to parse + * @return an Object that text represented + * @throws ParseException if there is an error in the conversion + */ + public abstract Object stringToValue(String text) + throws ParseException; + + /** + * Returns a String to be displayed, based on the Object + * value. + * + * @param value the Object from which to generate a String + * @return a String to be displayed + * @throws ParseException if there is an error in the conversion + */ + public abstract String valueToString(Object value) + throws ParseException; + } + + /** + * Delivers instances of an {@link AbstractFormatter} for + * a specific value type for a JFormattedTextField. + */ + public abstract static class AbstractFormatterFactory + { + public AbstractFormatterFactory() + { + // Do nothing here. + } + + public abstract AbstractFormatter getFormatter(JFormattedTextField tf); + } + + /** The possible focusLostBehavior options **/ + public static final int COMMIT = 0; + public static final int COMMIT_OR_REVERT = 1; + public static final int REVERT = 2; + public static final int PERSIST = 3; + + /** The most recent valid and committed value **/ + private Object value; + + /** The behaviour for when this text field loses focus **/ + private int focusLostBehavior = COMMIT_OR_REVERT; + + /** The formatter factory currently being used **/ + private AbstractFormatterFactory formatterFactory; + + /** The formatter currently being used **/ + private AbstractFormatter formatter; + + // Package-private to avoid an accessor method. + boolean editValid = true; + + /** + * Creates a JFormattedTextField with no formatter factory. + * setValue or setFormatterFactory will + * properly configure this text field to edit a particular type + * of value. + */ + public JFormattedTextField() + { + this((AbstractFormatterFactory) null, null); + } + + /** + * Creates a JFormattedTextField that can handle the specified Format. + * An appopriate AbstractFormatter and AbstractFormatterFactory will + * be created for the specified Format. + * + * @param format the Format that this JFormattedTextField should be able + * to handle + */ + public JFormattedTextField(Format format) + { + this (); + setFormatterFactory(getAppropriateFormatterFactory(format)); + } + + /** + * Creates a JFormattedTextField with the specified formatter. This will + * create a {@link DefaultFormatterFactory} with this formatter as the default + * formatter. + * + * @param formatter the formatter to use for this JFormattedTextField + */ + public JFormattedTextField(AbstractFormatter formatter) + { + this(new DefaultFormatterFactory(formatter)); + } + + /** + * Creates a JFormattedTextField with the specified formatter factory. + * + * @param factory the formatter factory to use for this JFormattedTextField + */ + public JFormattedTextField(AbstractFormatterFactory factory) + { + setFormatterFactory(factory); + } + + /** + * Creates a JFormattedTextField with the specified formatter factory and + * initial value. + * + * @param factory the initial formatter factory for this JFormattedTextField + * @param value the initial value for the text field + */ + public JFormattedTextField(AbstractFormatterFactory factory, Object value) + { + setFormatterFactory(factory); + setValue(value); + } + + /** + * Creates a JFormattedTextField with the specified value. This creates a + * formatter and formatterFactory that are appropriate for the value. + * + * @param value the initial value for this JFormattedTextField + */ + public JFormattedTextField(Object value) + { + setValue(value); + } + + /** + * Returns an AbstractFormatterFactory that will give an appropriate + * AbstractFormatter for the given Format. + * @param format the Format to match with an AbstractFormatter. + * @return a DefaultFormatterFactory whose defaultFormatter is appropriate + * for the given Format. + */ + private AbstractFormatterFactory getAppropriateFormatterFactory(Format format) + { + AbstractFormatter newFormatter; + if (format instanceof DateFormat) + newFormatter = new DateFormatter((DateFormat) format); + else if (format instanceof NumberFormat) + newFormatter = new NumberFormatter ((NumberFormat) format); + else + newFormatter = new InternationalFormatter(format); + + return new DefaultFormatterFactory(newFormatter); + } + + /** + * Forces the current value from the editor to be set as the current + * value. If there is no current formatted this has no effect. + * + * @throws ParseException if the formatter cannot format the current value + */ + public void commitEdit() + throws ParseException + { + if (formatter == null) + return; + // Note: this code is a lot like setValue except that we don't want + // to create a new formatter. + Object oldValue = this.value; + + this.value = formatter.stringToValue(getText()); + editValid = true; + + firePropertyChange("value", oldValue, this.value); + } + + /** + * Gets the command list supplied by the UI augmented by the specific + * Actions for JFormattedTextField. + * + * @return an array of Actions that this text field supports + */ + public Action[] getActions() + { + // FIXME: Add JFormattedTextField specific actions + // These are related to committing or cancelling edits. + return super.getActions(); + } + + /** + * Returns the behaviour of this JFormattedTextField upon losing focus. This + * is one of COMMIT, COMMIT_OR_REVERT, + * PERSIST, or REVERT. + * @return the behaviour upon losing focus + */ + public int getFocusLostBehavior() + { + return focusLostBehavior; + } + + /** + * Returns the current formatter used for this JFormattedTextField. + * @return the current formatter used for this JFormattedTextField + */ + public AbstractFormatter getFormatter() + { + return formatter; + } + + /** + * Returns the factory currently used to generate formatters for this + * JFormattedTextField. + * @return the factory currently used to generate formatters + */ + public AbstractFormatterFactory getFormatterFactory() + { + return formatterFactory; + } + + public String getUIClassID() + { + return "FormattedTextFieldUI"; + } + + /** + * Returns the last valid value. This may not be the value currently shown + * in the text field depending on whether or not the formatter commits on + * valid edits and allows invalid input to be temporarily displayed. + * @return the last committed valid value + */ + public Object getValue() + { + return value; + } + + /** + * This method is used to provide feedback to the user when an invalid value + * is input during editing. + */ + protected void invalidEdit() + { + UIManager.getLookAndFeel().provideErrorFeedback(this); + } + + /** + * Returns true if the current value being edited is valid. This property is + * managed by the current formatted. + * @return true if the value being edited is valid. + */ + public boolean isEditValid() + { + return editValid; + } + + /** + * Processes focus events. This is overridden because we may want to + * change the formatted depending on whether or not this field has + * focus. + * + * @param evt the FocusEvent + */ + protected void processFocusEvent(FocusEvent evt) + { + super.processFocusEvent(evt); + // Let the formatterFactory change the formatter for this text field + // based on whether or not it has focus. + setFormatter (formatterFactory.getFormatter(this)); + } + + /** + * Associates this JFormattedTextField with a Document and propagates + * a PropertyChange event to each listener. + * + * @param newDocument the Document to associate with this text field + */ + public void setDocument(Document newDocument) + { + // FIXME: This method should do more than this. Must do some handling + // of the DocumentListeners. + Document oldDocument = getDocument(); + + if (oldDocument == newDocument) + return; + + super.setDocument(newDocument); + } + + /** + * Sets the behaviour of this JFormattedTextField upon losing focus. + * This must be COMMIT, COMMIT_OR_REVERT, + * PERSIST, or REVERT or an + * IllegalArgumentException will be thrown. + * + * @param behavior + * @throws IllegalArgumentException if behaviour is not + * one of the above + */ + public void setFocusLostBehavior(int behavior) + { + if (behavior != COMMIT + && behavior != COMMIT_OR_REVERT + && behavior != PERSIST + && behavior != REVERT) + throw new IllegalArgumentException("invalid behavior"); + + this.focusLostBehavior = behavior; + } + + /** + * Sets the formatter for this JFormattedTextField. Normally the formatter + * factory will take care of this, or calls to setValue will also make sure + * that the formatter is set appropriately. + * + * @param formatter the AbstractFormatter to use for formatting the value for + * this JFormattedTextField + */ + protected void setFormatter(AbstractFormatter formatter) + { + AbstractFormatter oldFormatter = null; + + oldFormatter = this.formatter; + + if (oldFormatter != null) + oldFormatter.uninstall(); + + this.formatter = formatter; + + if (formatter != null) + formatter.install(this); + + firePropertyChange("formatter", oldFormatter, formatter); + } + + /** + * Sets the factory from which this JFormattedTextField should obtain + * its formatters. + * + * @param factory the AbstractFormatterFactory that will be used to generate + * formatters for this JFormattedTextField + */ + public void setFormatterFactory(AbstractFormatterFactory factory) + { + if (formatterFactory == factory) + return; + + AbstractFormatterFactory oldFactory = formatterFactory; + formatterFactory = factory; + firePropertyChange("formatterFactory", oldFactory, factory); + + // Now set the formatter according to our new factory. + if (formatterFactory != null) + setFormatter(formatterFactory.getFormatter(this)); + else + setFormatter(null); + } + + /** + * Sets the value that will be formatted and displayed. + * + * @param newValue the value to be formatted and displayed + */ + public void setValue(Object newValue) + { + if (value == newValue) + return; + + Object oldValue = value; + value = newValue; + + // If there is no formatterFactory then make one. + if (formatterFactory == null) + setFormatterFactory(createFormatterFactory(newValue)); + + // Set the formatter appropriately. This is because there may be a new + // formatterFactory from the line above, or we may want a new formatter + // depending on the type of newValue (or if newValue is null). + setFormatter (formatterFactory.getFormatter(this)); + firePropertyChange("value", oldValue, newValue); + } + + /** + * A helper method that attempts to create a formatter factory that is + * suitable to format objects of the type like value. + * + * @param value an object which should be formatted by the formatter factory. + * + * @return a formatter factory able to format objects of the class of + * value + */ + AbstractFormatterFactory createFormatterFactory(Object value) + { + AbstractFormatter formatter = null; + if (value instanceof Date) + formatter = new DateFormatter(); + else if (value instanceof Number) + formatter = new NumberFormatter(); + else + formatter = new DefaultFormatter(); + return new DefaultFormatterFactory(formatter); + } +} -- cgit v1.2.3