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);
 | 
						|
  }
 | 
						|
 | 
						|
}
 |