5073 lines · 187.2 KB · Java
RawDownload
/* * Copyright (c) 1997, 2011, 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.text; import java.lang.reflect.Method; import java.security.AccessController;import java.security.PrivilegedAction; import java.beans.Transient;import java.util.Collections;import java.util.HashMap;import java.util.Hashtable;import java.util.Enumeration;import java.util.Vector;import java.util.Map; import java.util.concurrent.*; import java.io.*; import java.awt.*;import java.awt.event.*;import java.awt.print.*;import java.awt.datatransfer.*;import java.awt.im.InputContext;import java.awt.im.InputMethodRequests;import java.awt.font.TextHitInfo;import java.awt.font.TextAttribute; import java.awt.print.Printable;import java.awt.print.PrinterException; import javax.print.PrintService;import javax.print.attribute.PrintRequestAttributeSet; import java.text.*;import java.text.AttributedCharacterIterator.Attribute; import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*; import javax.accessibility.*; import javax.print.attribute.*; import sun.awt.AppContext;  import sun.swing.PrintingStatus;import sun.swing.SwingUtilities2;import sun.swing.text.TextComponentPrintable;import sun.swing.SwingAccessor; /** * <code>JTextComponent</code> is the base class for swing text * components.  It tries to be compatible with the * <code>java.awt.TextComponent</code> class * where it can reasonably do so.  Also provided are other services * for additional flexibility (beyond the pluggable UI and bean * support). * You can find information on how to use the functionality * this class provides in * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/generaltext.html">General Rules for Using Text Components</a>, * a section in <em>The Java Tutorial.</em> * * <p> * <dl> * <dt><b><font size=+1>Caret Changes</font></b> * <dd> * The caret is a pluggable object in swing text components. * Notification of changes to the caret position and the selection * are sent to implementations of the <code>CaretListener</code> * interface that have been registered with the text component. * The UI will install a default caret unless a customized caret * has been set. <br> * By default the caret tracks all the document changes * performed on the Event Dispatching Thread and updates it's position * accordingly if an insertion occurs before or at the caret position * or a removal occurs before the caret position. <code>DefaultCaret</code> * tries to make itself visible which may lead to scrolling * of a text component within <code>JScrollPane</code>. The default caret * behavior can be changed by the {@link DefaultCaret#setUpdatePolicy} method. * <br> * <b>Note</b>: Non-editable text components also have a caret though * it may not be painted. * * <p> * <dt><b><font size=+1>Commands</font></b> * <dd> * Text components provide a number of commands that can be used * to manipulate the component.  This is essentially the way that * the component expresses its capabilities.  These are expressed * in terms of the swing <code>Action</code> interface, * using the <code>TextAction</code> implementation. * The set of commands supported by the text component can be * found with the {@link #getActions} method.  These actions * can be bound to key events, fired from buttons, etc. * * <p> * <dt><b><font size=+1>Text Input</font></b> * <dd> * The text components support flexible and internationalized text input, using * keymaps and the input method framework, while maintaining compatibility with * the AWT listener model. * <p> * A {@link javax.swing.text.Keymap} lets an application bind key * strokes to actions. * In order to allow keymaps to be shared across multiple text components, they * can use actions that extend <code>TextAction</code>. * <code>TextAction</code> can determine which <code>JTextComponent</code> * most recently has or had focus and therefore is the subject of * the action (In the case that the <code>ActionEvent</code> * sent to the action doesn't contain the target text component as its source). * <p> * The <a href="../../../../technotes/guides/imf/spec.html">input method framework</a> * lets text components interact with input methods, separate software * components that preprocess events to let users enter thousands of * different characters using keyboards with far fewer keys. * <code>JTextComponent</code> is an <em>active client</em> of * the framework, so it implements the preferred user interface for interacting * with input methods. As a consequence, some key events do not reach the text * component because they are handled by an input method, and some text input * reaches the text component as committed text within an {@link * java.awt.event.InputMethodEvent} instead of as a key event. * The complete text input is the combination of the characters in * <code>keyTyped</code> key events and committed text in input method events. * <p> * The AWT listener model lets applications attach event listeners to * components in order to bind events to actions. Swing encourages the * use of keymaps instead of listeners, but maintains compatibility * with listeners by giving the listeners a chance to steal an event * by consuming it. * <p> * Keyboard event and input method events are handled in the following stages, * with each stage capable of consuming the event: * * <table border=1 summary="Stages of keyboard and input method event handling"> * <tr> * <th id="stage"><p align="left">Stage</p></th> * <th id="ke"><p align="left">KeyEvent</p></th> * <th id="ime"><p align="left">InputMethodEvent</p></th></tr> * <tr><td headers="stage">1.   </td> *     <td headers="ke">input methods </td> *     <td headers="ime">(generated here)</td></tr> * <tr><td headers="stage">2.   </td> *     <td headers="ke">focus manager </td> *     <td headers="ime"></td> * </tr> * <tr> *     <td headers="stage">3.   </td> *     <td headers="ke">registered key listeners</td> *     <td headers="ime">registered input method listeners</tr> * <tr> *     <td headers="stage">4.   </td> *     <td headers="ke"></td> *     <td headers="ime">input method handling in JTextComponent</tr> * <tr> *     <td headers="stage">5.   </td><td headers="ke ime" colspan=2>keymap handling using the current keymap</td></tr> * <tr><td headers="stage">6.   </td><td headers="ke">keyboard handling in JComponent (e.g. accelerators, component navigation, etc.)</td> *     <td headers="ime"></td></tr> * </table> * * <p> * To maintain compatibility with applications that listen to key * events but are not aware of input method events, the input * method handling in stage 4 provides a compatibility mode for * components that do not process input method events. For these * components, the committed text is converted to keyTyped key events * and processed in the key event pipeline starting at stage 3 * instead of in the input method event pipeline. * <p> * By default the component will create a keymap (named <b>DEFAULT_KEYMAP</b>) * that is shared by all JTextComponent instances as the default keymap. * Typically a look-and-feel implementation will install a different keymap * that resolves to the default keymap for those bindings not found in the * different keymap. The minimal bindings include: * <ul> * <li>inserting content into the editor for the *  printable keys. * <li>removing content with the backspace and del *  keys. * <li>caret movement forward and backward * </ul> * * <p> * <dt><b><font size=+1>Model/View Split</font></b> * <dd> * The text components have a model-view split.  A text component pulls * together the objects used to represent the model, view, and controller. * The text document model may be shared by other views which act as observers * of the model (e.g. a document may be shared by multiple components). * * <p align=center><img src="doc-files/editor.gif" alt="Diagram showing interaction between Controller, Document, events, and ViewFactory" *                  HEIGHT=358 WIDTH=587></p> * * <p> * The model is defined by the {@link Document} interface. * This is intended to provide a flexible text storage mechanism * that tracks change during edits and can be extended to more sophisticated * models.  The model interfaces are meant to capture the capabilities of * expression given by SGML, a system used to express a wide variety of * content. * Each modification to the document causes notification of the * details of the change to be sent to all observers in the form of a * {@link DocumentEvent} which allows the views to stay up to date with the model. * This event is sent to observers that have implemented the * {@link DocumentListener} * interface and registered interest with the model being observed. * * <p> * <dt><b><font size=+1>Location Information</font></b> * <dd> * The capability of determining the location of text in * the view is provided.  There are two methods, {@link #modelToView} * and {@link #viewToModel} for determining this information. * * <p> * <dt><b><font size=+1>Undo/Redo support</font></b> * <dd> * Support for an edit history mechanism is provided to allow * undo/redo operations.  The text component does not itself * provide the history buffer by default, but does provide * the <code>UndoableEdit</code> records that can be used in conjunction * with a history buffer to provide the undo/redo support. * The support is provided by the Document model, which allows * one to attach UndoableEditListener implementations. * * <p> * <dt><b><font size=+1>Thread Safety</font></b> * <dd> * The swing text components provide some support of thread * safe operations.  Because of the high level of configurability * of the text components, it is possible to circumvent the * protection provided.  The protection primarily comes from * the model, so the documentation of <code>AbstractDocument</code> * describes the assumptions of the protection provided. * The methods that are safe to call asynchronously are marked * with comments. * * <p> * <dt><b><font size=+1>Newlines</font></b> * <dd> * For a discussion on how newlines are handled, see * <a href="DefaultEditorKit.html">DefaultEditorKit</a>. * * <p> * <dt><b><font size=+1>Printing support</font></b> * <dd> * Several {@link #print print} methods are provided for basic * document printing.  If more advanced printing is needed, use the * {@link #getPrintable} method. * </dl> * * <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<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @beaninfo *     attribute: isContainer false * * @author  Timothy Prinzing * @author Igor Kushnirskiy (printing support) * @see Document * @see DocumentEvent * @see DocumentListener * @see Caret * @see CaretEvent * @see CaretListener * @see TextUI * @see View * @see ViewFactory */public abstract class JTextComponent extends JComponent implements Scrollable, Accessible{    /**     * Creates a new <code>JTextComponent</code>.     * Listeners for caret events are established, and the pluggable     * UI installed.  The component is marked as editable.  No layout manager     * is used, because layout is managed by the view subsystem of text.     * The document model is set to <code>null</code>.     */    public JTextComponent() {        super();        // enable InputMethodEvent for on-the-spot pre-editing        enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK);        caretEvent = new MutableCaretEvent(this);        addMouseListener(caretEvent);        addFocusListener(caretEvent);        setEditable(true);        setDragEnabled(false);        setLayout(null); // layout is managed by View hierarchy        updateUI();    }     /**     * Fetches the user-interface factory for this text-oriented editor.     *     * @return the factory     */    public TextUI getUI() { return (TextUI)ui; }     /**     * Sets the user-interface factory for this text-oriented editor.     *     * @param ui the factory     */    public void setUI(TextUI ui) {        super.setUI(ui);    }     /**     * Reloads the pluggable UI.  The key used to fetch the     * new interface is <code>getUIClassID()</code>.  The type of     * the UI is <code>TextUI</code>.  <code>invalidate</code>     * is called after setting the UI.     */    public void updateUI() {        setUI((TextUI)UIManager.getUI(this));        invalidate();    }     /**     * Adds a caret listener for notification of any changes     * to the caret.     *     * @param listener the listener to be added     * @see javax.swing.event.CaretEvent     */    public void addCaretListener(CaretListener listener) {        listenerList.add(CaretListener.class, listener);    }     /**     * Removes a caret listener.     *     * @param listener the listener to be removed     * @see javax.swing.event.CaretEvent     */    public void removeCaretListener(CaretListener listener) {        listenerList.remove(CaretListener.class, listener);    }     /**     * Returns an array of all the caret listeners     * registered on this text component.     *     * @return all of this component's <code>CaretListener</code>s     *         or an empty     *         array if no caret listeners are currently registered     *     * @see #addCaretListener     * @see #removeCaretListener     *     * @since 1.4     */    public CaretListener[] getCaretListeners() {        return listenerList.getListeners(CaretListener.class);    }     /**     * Notifies all listeners that have registered interest for     * notification on this event type.  The event instance     * is lazily created using the parameters passed into     * the fire method.  The listener list is processed in a     * last-to-first manner.     *     * @param e the event     * @see EventListenerList     */    protected void fireCaretUpdate(CaretEvent e) {        // Guaranteed to return a non-null array        Object[] listeners = listenerList.getListenerList();        // Process the listeners last to first, notifying        // those that are interested in this event        for (int i = listeners.length-2; i>=0; i-=2) {            if (listeners[i]==CaretListener.class) {                ((CaretListener)listeners[i+1]).caretUpdate(e);            }        }    }     /**     * 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     */    public void setDocument(Document doc) {        Document old = model;         /*         * aquire a read lock on the old model to prevent notification of         * mutations while we disconnecting the old model.         */        try {            if (old instanceof AbstractDocument) {                ((AbstractDocument)old).readLock();            }            if (accessibleContext != null) {                model.removeDocumentListener(                    ((AccessibleJTextComponent)accessibleContext));            }            if (inputMethodRequestsHandler != null) {                model.removeDocumentListener((DocumentListener)inputMethodRequestsHandler);            }            model = doc;             // Set the document's run direction property to match the            // component's ComponentOrientation property.            Boolean runDir = getComponentOrientation().isLeftToRight()                             ? TextAttribute.RUN_DIRECTION_LTR                             : TextAttribute.RUN_DIRECTION_RTL;            if (runDir != doc.getProperty(TextAttribute.RUN_DIRECTION)) {                doc.putProperty(TextAttribute.RUN_DIRECTION, runDir );            }            firePropertyChange("document", old, doc);        } finally {            if (old instanceof AbstractDocument) {                ((AbstractDocument)old).readUnlock();            }        }         revalidate();        repaint();        if (accessibleContext != null) {            model.addDocumentListener(                ((AccessibleJTextComponent)accessibleContext));        }        if (inputMethodRequestsHandler != null) {            model.addDocumentListener((DocumentListener)inputMethodRequestsHandler);        }    }     /**     * Fetches the model associated with the editor.  This is     * primarily for the UI to get at the minimal amount of     * state required to be a text editor.  Subclasses will     * return the actual type of the model which will typically     * be something that extends Document.     *     * @return the model     */    public Document getDocument() {        return model;    }     // Override of Component.setComponentOrientation    public void setComponentOrientation( ComponentOrientation o ) {        // Set the document's run direction property to match the        // ComponentOrientation property.        Document doc = getDocument();        if( doc !=  null ) {            Boolean runDir = o.isLeftToRight()                             ? TextAttribute.RUN_DIRECTION_LTR                             : TextAttribute.RUN_DIRECTION_RTL;            doc.putProperty( TextAttribute.RUN_DIRECTION, runDir );        }        super.setComponentOrientation( o );    }     /**     * Fetches the command list for the editor.  This is     * the list of commands supported by the plugged-in UI

Lines 1–500 of 5073.