/* * 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 UILines 1–500 of 5073. Load more
/* * 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