mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			571 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			571 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* JTextField.java --
 | |
|    Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | |
| 02110-1301 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| 
 | |
| package javax.swing;
 | |
| 
 | |
| import java.awt.Dimension;
 | |
| import java.awt.Font;
 | |
| import java.awt.FontMetrics;
 | |
| import java.awt.Insets;
 | |
| import java.awt.Rectangle;
 | |
| import java.awt.event.ActionEvent;
 | |
| import java.awt.event.ActionListener;
 | |
| import java.beans.PropertyChangeEvent;
 | |
| import java.beans.PropertyChangeListener;
 | |
| 
 | |
| import javax.accessibility.AccessibleContext;
 | |
| import javax.accessibility.AccessibleStateSet;
 | |
| import javax.swing.text.Document;
 | |
| import javax.swing.text.JTextComponent;
 | |
| import javax.swing.text.PlainDocument;
 | |
| import javax.swing.text.TextAction;
 | |
| 
 | |
| public class JTextField extends JTextComponent
 | |
|   implements SwingConstants
 | |
| {
 | |
|   /**
 | |
|    * AccessibleJTextField
 | |
|    */
 | |
|   protected class AccessibleJTextField extends AccessibleJTextComponent
 | |
|   {
 | |
|     private static final long serialVersionUID = 8255147276740453036L;
 | |
| 
 | |
|     /**
 | |
|      * Constructor AccessibleJTextField
 | |
|      */
 | |
|     protected AccessibleJTextField()
 | |
|     {
 | |
|       super();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Returns the accessible state of this <code>AccessibleJTextField</code>.
 | |
|      *
 | |
|      * @return the accessible state of this <code>AccessibleJTextField</code>
 | |
|      */
 | |
|     public AccessibleStateSet getAccessibleStateSet()
 | |
|     {
 | |
|       AccessibleStateSet state = super.getAccessibleStateSet();
 | |
|       // TODO: Figure out what state must be added here to the super's state.
 | |
|       return state;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   private static final long serialVersionUID = 353853209832607592L;
 | |
| 
 | |
|   private static final Action[] actions;
 | |
| 
 | |
|   /**
 | |
|    * Name of the action that gets sent when the content of the text field
 | |
|    * gets accepted.
 | |
|    */
 | |
|   public static final String notifyAction = "notify-field-accept";
 | |
| 
 | |
|   static
 | |
|     {
 | |
|       actions = new Action[1];
 | |
|       actions[0] = new TextAction(notifyAction)
 | |
|       {
 | |
|         public void actionPerformed(ActionEvent event)
 | |
|         {
 | |
|           JTextField textField = (JTextField) event.getSource();
 | |
|           textField.fireActionPerformed();
 | |
|         }
 | |
|       };
 | |
|     }
 | |
| 
 | |
|   private int columns;
 | |
|   private int align;
 | |
| 
 | |
|   /** @since 1.3 */
 | |
|   private Action action;
 | |
| 
 | |
|   /** @since 1.3 */
 | |
|   private String actionCommand;
 | |
| 
 | |
|   private PropertyChangeListener actionPropertyChangeListener;
 | |
| 
 | |
|   /**
 | |
|    * The horizontal visibility of the textfield.
 | |
|    */
 | |
|   private BoundedRangeModel horizontalVisibility;
 | |
| 
 | |
|   /**
 | |
|    * Creates a new instance of <code>JTextField</code>.
 | |
|    */
 | |
|   public JTextField()
 | |
|   {
 | |
|     this(null, null, 0);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates a new instance of <code>JTextField</code>.
 | |
|    *
 | |
|    * @param text the initial text
 | |
|    */
 | |
|   public JTextField(String text)
 | |
|   {
 | |
|     this(null, text, 0);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates a new instance of <code>JTextField</code>.
 | |
|    *
 | |
|    * @param columns the number of columns
 | |
|    *
 | |
|    * @exception IllegalArgumentException if columns %lt; 0
 | |
|    */
 | |
|   public JTextField(int columns)
 | |
|   {
 | |
|     this(null, null, columns);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates a new instance of <code>JTextField</code>.
 | |
|    *
 | |
|    * @param text the initial text
 | |
|    * @param columns the number of columns
 | |
|    *
 | |
|    * @exception IllegalArgumentException if columns %lt; 0
 | |
|    */
 | |
|   public JTextField(String text, int columns)
 | |
|   {
 | |
|     this(null, text, columns);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates a new instance of <code>JTextField</code>.
 | |
|    *
 | |
|    * @param doc the document to use
 | |
|    * @param text the initial text
 | |
|    * @param columns the number of columns
 | |
|    *
 | |
|    * @exception IllegalArgumentException if columns %lt; 0
 | |
|    */
 | |
|   public JTextField(Document doc, String text, int columns)
 | |
|   {
 | |
|     if (columns < 0)
 | |
|       throw new IllegalArgumentException();
 | |
| 
 | |
|     this.columns = columns;
 | |
| 
 | |
|     // Initialize the horizontal visibility model.
 | |
|     horizontalVisibility = new DefaultBoundedRangeModel();
 | |
| 
 | |
|     setDocument(doc == null ? createDefaultModel() : doc);
 | |
| 
 | |
|     if (text != null)
 | |
|       setText(text);
 | |
| 
 | |
|     // default value for alignment
 | |
|     align = LEADING;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates the default model for this text field.
 | |
|    * This implementation returns an instance of <code>PlainDocument</code>.
 | |
|    *
 | |
|    * @return a new instance of the default model
 | |
|    */
 | |
|   protected Document createDefaultModel()
 | |
|   {
 | |
|     return new PlainDocument();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the document to be used for this JTextField.
 | |
|    *
 | |
|    * This sets the document property <code>filterNewlines</code> to
 | |
|    * <code>true</code> and then calls the super behaviour to setup a view and
 | |
|    * revalidate the text field.
 | |
|    *
 | |
|    * @param doc the document to set
 | |
|    */
 | |
|   public void setDocument(Document doc)
 | |
|   {
 | |
|     doc.putProperty("filterNewlines", Boolean.TRUE);
 | |
|     super.setDocument(doc);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the class ID for the UI.
 | |
|    *
 | |
|    * @return "TextFieldUI";
 | |
|    */
 | |
|   public String getUIClassID()
 | |
|   {
 | |
|     return "TextFieldUI";
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Adds a new listener object to this text field.
 | |
|    *
 | |
|    * @param listener the listener to add
 | |
|    */
 | |
|   public void addActionListener(ActionListener listener)
 | |
|   {
 | |
|     listenerList.add(ActionListener.class, listener);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Removes a listener object from this text field.
 | |
|    *
 | |
|    * @param listener the listener to remove
 | |
|    */
 | |
|   public void removeActionListener(ActionListener listener)
 | |
|   {
 | |
|     listenerList.remove(ActionListener.class, listener);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns all registered <code>ActionListener</code> objects.
 | |
|    *
 | |
|    * @return an array of listeners
 | |
|    *
 | |
|    * @since 1.4
 | |
|    */
 | |
|   public ActionListener[] getActionListeners()
 | |
|   {
 | |
|     return (ActionListener[]) getListeners(ActionListener.class);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sends an action event to all registered
 | |
|    * <code>ActionListener</code> objects.
 | |
|    */
 | |
|   protected void fireActionPerformed()
 | |
|   {
 | |
|     ActionEvent event = new ActionEvent(this, 0,
 | |
|                           actionCommand == null ? getText() : actionCommand);
 | |
|     ActionListener[] listeners = getActionListeners();
 | |
| 
 | |
|     for (int index = 0; index < listeners.length; ++index)
 | |
|       listeners[index].actionPerformed(event);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the number of columns of this text field.
 | |
|    *
 | |
|    * @return the number of columns
 | |
|    */
 | |
|   public int getColumns()
 | |
|   {
 | |
|     return columns;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the number of columns and then invalidates the layout.
 | |
|    * @param columns the number of columns
 | |
|    * @throws IllegalArgumentException if columns < 0
 | |
|    */
 | |
|   public void setColumns(int columns)
 | |
|   {
 | |
|     if (columns < 0)
 | |
|       throw new IllegalArgumentException();
 | |
| 
 | |
|     this.columns = columns;
 | |
|     invalidate();
 | |
|     //FIXME: do we need this repaint call?
 | |
|     repaint();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the horizontal alignment, which is one of: JTextField.LEFT,
 | |
|    * JTextField.CENTER, JTextField.RIGHT, JTextField.LEADING,
 | |
|    * JTextField.TRAILING.
 | |
|    * @return the horizontal alignment
 | |
|    */
 | |
|   public int getHorizontalAlignment()
 | |
|   {
 | |
|     return align;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the horizontal alignment of the text.  Calls invalidate and repaint
 | |
|    * and fires a property change event.
 | |
|    * @param newAlign must be one of: JTextField.LEFT, JTextField.CENTER,
 | |
|    * JTextField.RIGHT, JTextField.LEADING, JTextField.TRAILING.
 | |
|    * @throws IllegalArgumentException if newAlign is not one of the above.
 | |
|    */
 | |
|   public void setHorizontalAlignment(int newAlign)
 | |
|   {
 | |
|     //FIXME: should throw an IllegalArgumentException if newAlign is invalid
 | |
|     if (align == newAlign)
 | |
|       return;
 | |
| 
 | |
|     int oldAlign = align;
 | |
|     align = newAlign;
 | |
|     firePropertyChange("horizontalAlignment", oldAlign, newAlign);
 | |
|     invalidate();
 | |
|     repaint();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the current font and revalidates so the font will take effect.
 | |
|    */
 | |
|   public void setFont(Font newFont)
 | |
|   {
 | |
|     super.setFont(newFont);
 | |
|     revalidate();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the preferred size.  If there is a non-zero number of columns,
 | |
|    * this is the number of columns multiplied by the column width, otherwise
 | |
|    * it returns super.getPreferredSize().
 | |
|    */
 | |
|   public Dimension getPreferredSize()
 | |
|   {
 | |
|     Dimension size = super.getPreferredSize();
 | |
| 
 | |
|     if (columns != 0)
 | |
|       {
 | |
|         Insets i = getInsets();
 | |
|         size.width = columns * getColumnWidth() + i.left + i.right;
 | |
|       }
 | |
| 
 | |
|     return size;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the scroll offset in pixels.
 | |
|    *
 | |
|    * @return the scroll offset
 | |
|    */
 | |
|   public int getScrollOffset()
 | |
|   {
 | |
|     return horizontalVisibility.getValue();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the scroll offset in pixels.
 | |
|    *
 | |
|    * @param offset the scroll offset
 | |
|    */
 | |
|   public void setScrollOffset(int offset)
 | |
|   {
 | |
|     // Automatically sets to the highest possible value if
 | |
|     // offset is bigger than that.
 | |
|     horizontalVisibility.setValue(
 | |
|                                   Math.min(horizontalVisibility.getMaximum()
 | |
|                                            - horizontalVisibility.getExtent(),
 | |
|                                            offset));
 | |
| 
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the set of Actions that are commands for the editor.
 | |
|    * This is the actions supported by this editor plus the actions
 | |
|    * of the UI (returned by JTextComponent.getActions()).
 | |
|    */
 | |
|   public Action[] getActions()
 | |
|   {
 | |
|     return TextAction.augmentList(super.getActions(), actions);
 | |
|   }
 | |
| 
 | |
|   public void postActionEvent()
 | |
|   {
 | |
|     String command = actionCommand != null ? actionCommand : getText();
 | |
|     ActionEvent event = new ActionEvent(this, 0, command);
 | |
|     ActionListener[] listeners = getActionListeners();
 | |
| 
 | |
|     for (int index = 0; index < listeners.length; ++index)
 | |
|       listeners[index].actionPerformed(event);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @since 1.3
 | |
|    */
 | |
|   public Action getAction()
 | |
|   {
 | |
|     return action;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @since 1.3
 | |
|    */
 | |
|   public void setAction(Action newAction)
 | |
|   {
 | |
|     if (action == newAction)
 | |
|       return;
 | |
| 
 | |
|     if (action != null)
 | |
|       {
 | |
|         removeActionListener(action);
 | |
|         action.removePropertyChangeListener(actionPropertyChangeListener);
 | |
|         actionPropertyChangeListener = null;
 | |
|       }
 | |
| 
 | |
|     Action oldAction = action;
 | |
|     action = newAction;
 | |
| 
 | |
|     if (action != null)
 | |
|       {
 | |
|         addActionListener(action);
 | |
|         actionPropertyChangeListener = createActionPropertyChangeListener(action);
 | |
|         action.addPropertyChangeListener(actionPropertyChangeListener);
 | |
|       }
 | |
| 
 | |
|     //FIXME: is this a hack?  The horizontal alignment hasn't changed
 | |
|     firePropertyChange("horizontalAlignment", oldAction, newAction);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the command string used in action events.
 | |
|    * @since 1.3
 | |
|    */
 | |
|   public void setActionCommand(String command)
 | |
|   {
 | |
|     actionCommand = command;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @since 1.3
 | |
|    */
 | |
|   protected PropertyChangeListener createActionPropertyChangeListener(Action action)
 | |
|   {
 | |
|     return new PropertyChangeListener()
 | |
|     {
 | |
|       public void propertyChange(PropertyChangeEvent event)
 | |
|       {
 | |
|         // Update properties "action" and "horizontalAlignment".
 | |
|         String name = event.getPropertyName();
 | |
| 
 | |
|         if (name.equals("enabled"))
 | |
|           {
 | |
|             boolean enabled = ((Boolean) event.getNewValue()).booleanValue();
 | |
|             JTextField.this.setEnabled(enabled);
 | |
|           }
 | |
|         else if (name.equals(Action.SHORT_DESCRIPTION))
 | |
|           {
 | |
|             JTextField.this.setToolTipText((String) event.getNewValue());
 | |
|           }
 | |
|       }
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    *
 | |
|    * @since 1.3
 | |
|    */
 | |
|   protected void configurePropertiesFromAction(Action action)
 | |
|   {
 | |
|     if (action != null)
 | |
|       {
 | |
|         setEnabled(action.isEnabled());
 | |
|         setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
 | |
|       }
 | |
|     else
 | |
|       {
 | |
|         setEnabled(true);
 | |
|         setToolTipText(null);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the column width, which is the width of the character m
 | |
|    * for the font in use.
 | |
|    * @return the width of the character m for the font in use.
 | |
|    */
 | |
|   protected int getColumnWidth()
 | |
|   {
 | |
|     FontMetrics metrics = getToolkit().getFontMetrics(getFont());
 | |
|     return metrics.charWidth('m');
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the accessible context associated with the <code>JTextField</code>.
 | |
|    *
 | |
|    * @return the accessible context associated with the <code>JTextField</code>
 | |
|    */
 | |
|   public AccessibleContext getAccessibleContext()
 | |
|   {
 | |
|     if (accessibleContext == null)
 | |
|       accessibleContext = new AccessibleJTextField();
 | |
|     return accessibleContext;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the bounded range model that describes the horizontal visibility
 | |
|    * of the text field in the case when the text does not fit into the
 | |
|    * available space. The actual values of this model are managed by the look
 | |
|    * and feel implementation.
 | |
|    *
 | |
|    * @return the bounded range model that describes the horizontal visibility
 | |
|    */
 | |
|   public BoundedRangeModel getHorizontalVisibility()
 | |
|   {
 | |
|     return horizontalVisibility;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns <code>true</code>, unless this is embedded in a
 | |
|    * <code>JViewport</code> in which case the viewport takes responsibility of
 | |
|    * validating.
 | |
|    *
 | |
|    * @return <code>true</code>, unless this is embedded in a
 | |
|    *         <code>JViewport</code> in which case the viewport takes
 | |
|    *         responsibility of validating
 | |
|    */
 | |
|   public boolean isValidateRoot()
 | |
|   {
 | |
|     return ! (getParent() instanceof JViewport);
 | |
|   }
 | |
| 
 | |
|   public void scrollRectToVisible(Rectangle r)
 | |
|   {
 | |
|     int v = horizontalVisibility.getValue();
 | |
| 
 | |
|     // The extent value is the inner width of the text field.
 | |
|     int e = horizontalVisibility.getExtent();
 | |
|     Insets i = getInsets();
 | |
| 
 | |
|     // The x value in the rectangle (usually) denotes the new location
 | |
|     // of the caret. We check whether the location lies inside the left or
 | |
|     // right border and scroll into the appropriate direction.
 | |
|     // The calculation has to be shifted by the BoundedRangeModel's value
 | |
|     // because that value was already used to calculate r.x (this happens
 | |
|     // as part of a modelToView() call in FieldView).
 | |
|     if (r.x < i.left)
 | |
|       setScrollOffset(v + r.x - i.left);
 | |
|     else if (r.x > e + i.left)
 | |
|       setScrollOffset(r.x + v - e - i.left);
 | |
|   }
 | |
| 
 | |
| }
 |