jdk/src/share/classes/javax/swing/text/JTextComponent.java

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing.text;
  26 
  27 import com.sun.beans.util.Cache;
  28 
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 


  32 import java.beans.Transient;
  33 import java.util.HashMap;
  34 import java.util.Hashtable;
  35 import java.util.Enumeration;
  36 import java.util.Vector;
  37 
  38 import java.util.concurrent.*;
  39 
  40 import java.io.*;
  41 
  42 import java.awt.*;
  43 import java.awt.event.*;
  44 import java.awt.print.*;
  45 import java.awt.datatransfer.*;
  46 import java.awt.im.InputContext;
  47 import java.awt.im.InputMethodRequests;
  48 import java.awt.font.TextHitInfo;
  49 import java.awt.font.TextAttribute;
  50 
  51 import java.awt.print.Printable;
  52 import java.awt.print.PrinterException;
  53 
  54 import javax.print.PrintService;
  55 import javax.print.attribute.PrintRequestAttributeSet;
  56 
  57 import java.text.*;
  58 import java.text.AttributedCharacterIterator.Attribute;
  59 
  60 import javax.swing.*;
  61 import javax.swing.event.*;
  62 import javax.swing.plaf.*;
  63 
  64 import javax.accessibility.*;
  65 
  66 import javax.print.attribute.*;
  67 
  68 import sun.awt.AppContext;
  69 
  70 
  71 import sun.swing.PrintingStatus;
  72 import sun.swing.SwingUtilities2;
  73 import sun.swing.text.TextComponentPrintable;
  74 import sun.swing.SwingAccessor;
  75 
  76 /**
  77  * <code>JTextComponent</code> is the base class for swing text
  78  * components.  It tries to be compatible with the
  79  * <code>java.awt.TextComponent</code> class
  80  * where it can reasonably do so.  Also provided are other services
  81  * for additional flexibility (beyond the pluggable UI and bean
  82  * support).
  83  * You can find information on how to use the functionality
  84  * this class provides in
  85  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html">General Rules for Using Text Components</a>,
  86  * a section in <em>The Java Tutorial.</em>
  87  *
  88  * <dl>
  89  * <dt><b>Caret Changes</b>
  90  * <dd>


 258  * <a href="DefaultEditorKit.html">DefaultEditorKit</a>.
 259  *
 260  *
 261  * <dt><b>Printing support</b>
 262  * <dd>
 263  * Several {@link #print print} methods are provided for basic
 264  * document printing.  If more advanced printing is needed, use the
 265  * {@link #getPrintable} method.
 266  * </dl>
 267  *
 268  * <p>
 269  * <strong>Warning:</strong>
 270  * Serialized objects of this class will not be compatible with
 271  * future Swing releases. The current serialization support is
 272  * appropriate for short term storage or RMI between applications running
 273  * the same version of Swing.  As of 1.4, support for long term storage
 274  * of all JavaBeans&trade;
 275  * has been added to the <code>java.beans</code> package.
 276  * Please see {@link java.beans.XMLEncoder}.
 277  *
 278  * @beaninfo
 279  *     attribute: isContainer false
 280  *
 281  * @author  Timothy Prinzing
 282  * @author Igor Kushnirskiy (printing support)
 283  * @see Document
 284  * @see DocumentEvent
 285  * @see DocumentListener
 286  * @see Caret
 287  * @see CaretEvent
 288  * @see CaretListener
 289  * @see TextUI
 290  * @see View
 291  * @see ViewFactory
 292  */


 293 @SuppressWarnings("serial") // Same-version serialization only
 294 public abstract class JTextComponent extends JComponent implements Scrollable, Accessible
 295 {
 296     /**
 297      * Creates a new <code>JTextComponent</code>.
 298      * Listeners for caret events are established, and the pluggable
 299      * UI installed.  The component is marked as editable.  No layout manager
 300      * is used, because layout is managed by the view subsystem of text.
 301      * The document model is set to <code>null</code>.
 302      */
 303     public JTextComponent() {
 304         super();
 305         // enable InputMethodEvent for on-the-spot pre-editing
 306         enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK);
 307         caretEvent = new MutableCaretEvent(this);
 308         addMouseListener(caretEvent);
 309         addFocusListener(caretEvent);
 310         setEditable(true);
 311         setDragEnabled(false);
 312         setLayout(null); // layout is managed by View hierarchy


 357      * @param listener the listener to be removed
 358      * @see javax.swing.event.CaretEvent
 359      */
 360     public void removeCaretListener(CaretListener listener) {
 361         listenerList.remove(CaretListener.class, listener);
 362     }
 363 
 364     /**
 365      * Returns an array of all the caret listeners
 366      * registered on this text component.
 367      *
 368      * @return all of this component's <code>CaretListener</code>s
 369      *         or an empty
 370      *         array if no caret listeners are currently registered
 371      *
 372      * @see #addCaretListener
 373      * @see #removeCaretListener
 374      *
 375      * @since 1.4
 376      */

 377     public CaretListener[] getCaretListeners() {
 378         return listenerList.getListeners(CaretListener.class);
 379     }
 380 
 381     /**
 382      * Notifies all listeners that have registered interest for
 383      * notification on this event type.  The event instance
 384      * is lazily created using the parameters passed into
 385      * the fire method.  The listener list is processed in a
 386      * last-to-first manner.
 387      *
 388      * @param e the event
 389      * @see EventListenerList
 390      */
 391     protected void fireCaretUpdate(CaretEvent e) {
 392         // Guaranteed to return a non-null array
 393         Object[] listeners = listenerList.getListenerList();
 394         // Process the listeners last to first, notifying
 395         // those that are interested in this event
 396         for (int i = listeners.length-2; i>=0; i-=2) {
 397             if (listeners[i]==CaretListener.class) {
 398                 ((CaretListener)listeners[i+1]).caretUpdate(e);
 399             }
 400         }
 401     }
 402 
 403     /**
 404      * Associates the editor with a text document.
 405      * The currently registered factory is used to build a view for
 406      * the document, which gets displayed by the editor after revalidation.
 407      * A PropertyChange event ("document") is propagated to each listener.
 408      *
 409      * @param doc  the document to display/edit
 410      * @see #getDocument
 411      * @beaninfo
 412      *  description: the text document model
 413      *        bound: true
 414      *       expert: true
 415      */


 416     public void setDocument(Document doc) {
 417         Document old = model;
 418 
 419         /*
 420          * acquire a read lock on the old model to prevent notification of
 421          * mutations while we disconnecting the old model.
 422          */
 423         try {
 424             if (old instanceof AbstractDocument) {
 425                 ((AbstractDocument)old).readLock();
 426             }
 427             if (accessibleContext != null) {
 428                 model.removeDocumentListener(
 429                     ((AccessibleJTextComponent)accessibleContext));
 430             }
 431             if (inputMethodRequestsHandler != null) {
 432                 model.removeDocumentListener((DocumentListener)inputMethodRequestsHandler);
 433             }
 434             model = doc;
 435 


 478         // ComponentOrientation property.
 479         Document doc = getDocument();
 480         if( doc !=  null ) {
 481             Boolean runDir = o.isLeftToRight()
 482                              ? TextAttribute.RUN_DIRECTION_LTR
 483                              : TextAttribute.RUN_DIRECTION_RTL;
 484             doc.putProperty( TextAttribute.RUN_DIRECTION, runDir );
 485         }
 486         super.setComponentOrientation( o );
 487     }
 488 
 489     /**
 490      * Fetches the command list for the editor.  This is
 491      * the list of commands supported by the plugged-in UI
 492      * augmented by the collection of commands that the
 493      * editor itself supports.  These are useful for binding
 494      * to events, such as in a keymap.
 495      *
 496      * @return the command list
 497      */

 498     public Action[] getActions() {
 499         return getUI().getEditorKit(this).getActions();
 500     }
 501 
 502     /**
 503      * Sets margin space between the text component's border
 504      * and its text.  The text component's default <code>Border</code>
 505      * object will use this value to create the proper margin.
 506      * However, if a non-default border is set on the text component,
 507      * it is that <code>Border</code> object's responsibility to create the
 508      * appropriate margin space (else this property will effectively
 509      * be ignored).  This causes a redraw of the component.
 510      * A PropertyChange event ("margin") is sent to all listeners.
 511      *
 512      * @param m the space between the border and the text
 513      * @beaninfo
 514      *  description: desired space between the border and text area
 515      *        bound: true
 516      */


 517     public void setMargin(Insets m) {
 518         Insets old = margin;
 519         margin = m;
 520         firePropertyChange("margin", old, m);
 521         invalidate();
 522     }
 523 
 524     /**
 525      * Returns the margin between the text component's border and
 526      * its text.
 527      *
 528      * @return the margin
 529      */
 530     public Insets getMargin() {
 531         return margin;
 532     }
 533 
 534     /**
 535      * Sets the <code>NavigationFilter</code>. <code>NavigationFilter</code>
 536      * is used by <code>DefaultCaret</code> and the default cursor movement


 557 
 558     /**
 559      * Fetches the caret that allows text-oriented navigation over
 560      * the view.
 561      *
 562      * @return the caret
 563      */
 564     @Transient
 565     public Caret getCaret() {
 566         return caret;
 567     }
 568 
 569     /**
 570      * Sets the caret to be used.  By default this will be set
 571      * by the UI that gets installed.  This can be changed to
 572      * a custom caret if desired.  Setting the caret results in a
 573      * PropertyChange event ("caret") being fired.
 574      *
 575      * @param c the caret
 576      * @see #getCaret
 577      * @beaninfo
 578      *  description: the caret used to select/navigate
 579      *        bound: true
 580      *       expert: true
 581      */


 582     public void setCaret(Caret c) {
 583         if (caret != null) {
 584             caret.removeChangeListener(caretEvent);
 585             caret.deinstall(this);
 586         }
 587         Caret old = caret;
 588         caret = c;
 589         if (caret != null) {
 590             caret.install(this);
 591             caret.addChangeListener(caretEvent);
 592         }
 593         firePropertyChange("caret", old, caret);
 594     }
 595 
 596     /**
 597      * Fetches the object responsible for making highlights.
 598      *
 599      * @return the highlighter
 600      */
 601     public Highlighter getHighlighter() {
 602         return highlighter;
 603     }
 604 
 605     /**
 606      * Sets the highlighter to be used.  By default this will be set
 607      * by the UI that gets installed.  This can be changed to
 608      * a custom highlighter if desired.  The highlighter can be set to
 609      * <code>null</code> to disable it.
 610      * A PropertyChange event ("highlighter") is fired
 611      * when a new highlighter is installed.
 612      *
 613      * @param h the highlighter
 614      * @see #getHighlighter
 615      * @beaninfo
 616      *  description: object responsible for background highlights
 617      *        bound: true
 618      *       expert: true
 619      */


 620     public void setHighlighter(Highlighter h) {
 621         if (highlighter != null) {
 622             highlighter.deinstall(this);
 623         }
 624         Highlighter old = highlighter;
 625         highlighter = h;
 626         if (highlighter != null) {
 627             highlighter.install(this);
 628         }
 629         firePropertyChange("highlighter", old, h);
 630     }
 631 
 632     /**
 633      * Sets the keymap to use for binding events to
 634      * actions.  Setting to <code>null</code> effectively disables
 635      * keyboard input.
 636      * A PropertyChange event ("keymap") is fired when a new keymap
 637      * is installed.
 638      *
 639      * @param map the keymap
 640      * @see #getKeymap
 641      * @beaninfo
 642      *  description: set of key event to action bindings to use
 643      *        bound: true
 644      */


 645     public void setKeymap(Keymap map) {
 646         Keymap old = keymap;
 647         keymap = map;
 648         firePropertyChange("keymap", old, keymap);
 649         updateInputMap(old, map);
 650     }
 651 
 652     /**
 653      * Turns on or off automatic drag handling. In order to enable automatic
 654      * drag handling, this property should be set to {@code true}, and the
 655      * component's {@code TransferHandler} needs to be {@code non-null}.
 656      * The default value of the {@code dragEnabled} property is {@code false}.
 657      * <p>
 658      * The job of honoring this property, and recognizing a user drag gesture,
 659      * lies with the look and feel implementation, and in particular, the component's
 660      * {@code TextUI}. When automatic drag handling is enabled, most look and
 661      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
 662      * drag and drop operation whenever the user presses the mouse button over
 663      * a selection and then moves the mouse a few pixels. Setting this property to
 664      * {@code true} can therefore have a subtle effect on how selections behave.
 665      * <p>
 666      * If a look and feel is used that ignores this property, you can still
 667      * begin a drag and drop operation by calling {@code exportAsDrag} on the
 668      * component's {@code TransferHandler}.
 669      *
 670      * @param b whether or not to enable automatic drag handling
 671      * @exception HeadlessException if
 672      *            <code>b</code> is <code>true</code> and
 673      *            <code>GraphicsEnvironment.isHeadless()</code>
 674      *            returns <code>true</code>
 675      * @see java.awt.GraphicsEnvironment#isHeadless
 676      * @see #getDragEnabled
 677      * @see #setTransferHandler
 678      * @see TransferHandler
 679      * @since 1.4
 680      *
 681      * @beaninfo
 682      *  description: determines whether automatic drag handling is enabled
 683      *        bound: false
 684      */


 685     public void setDragEnabled(boolean b) {
 686         checkDragEnabled(b);
 687         dragEnabled = b;
 688     }
 689 
 690     private static void checkDragEnabled(boolean b) {
 691         if (b && GraphicsEnvironment.isHeadless()) {
 692             throw new HeadlessException();
 693         }
 694     }
 695 
 696     /**
 697      * Returns whether or not automatic drag handling is enabled.
 698      *
 699      * @return the value of the {@code dragEnabled} property
 700      * @see #setDragEnabled
 701      * @since 1.4
 702      */
 703     public boolean getDragEnabled() {
 704         return dragEnabled;


 936     }
 937 
 938     /**
 939      * Returns the location that this component should visually indicate
 940      * as the drop location during a DnD operation over the component,
 941      * or {@code null} if no location is to currently be shown.
 942      * <p>
 943      * This method is not meant for querying the drop location
 944      * from a {@code TransferHandler}, as the drop location is only
 945      * set after the {@code TransferHandler}'s <code>canImport</code>
 946      * has returned and has allowed for the location to be shown.
 947      * <p>
 948      * When this property changes, a property change event with
 949      * name "dropLocation" is fired by the component.
 950      *
 951      * @return the drop location
 952      * @see #setDropMode
 953      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
 954      * @since 1.6
 955      */

 956     public final DropLocation getDropLocation() {
 957         return dropLocation;
 958     }
 959 
 960 
 961     /**
 962      * Updates the <code>InputMap</code>s in response to a
 963      * <code>Keymap</code> change.
 964      * @param oldKm  the old <code>Keymap</code>
 965      * @param newKm  the new <code>Keymap</code>
 966      */
 967     void updateInputMap(Keymap oldKm, Keymap newKm) {
 968         // Locate the current KeymapWrapper.
 969         InputMap km = getInputMap(JComponent.WHEN_FOCUSED);
 970         InputMap last = km;
 971         while (km != null && !(km instanceof KeymapWrapper)) {
 972             last = km;
 973             km = km.getParent();
 974         }
 975         if (km != null) {


1201     }
1202 
1203     /**
1204      * Fetches the current color used to render the
1205      * caret.
1206      *
1207      * @return the color
1208      */
1209     public Color getCaretColor() {
1210         return caretColor;
1211     }
1212 
1213     /**
1214      * Sets the current color used to render the caret.
1215      * Setting to <code>null</code> effectively restores the default color.
1216      * Setting the color results in a PropertyChange event ("caretColor")
1217      * being fired.
1218      *
1219      * @param c the color
1220      * @see #getCaretColor
1221      * @beaninfo
1222      *  description: the color used to render the caret
1223      *        bound: true
1224      *    preferred: true
1225      */


1226     public void setCaretColor(Color c) {
1227         Color old = caretColor;
1228         caretColor = c;
1229         firePropertyChange("caretColor", old, caretColor);
1230     }
1231 
1232     /**
1233      * Fetches the current color used to render the
1234      * selection.
1235      *
1236      * @return the color
1237      */
1238     public Color getSelectionColor() {
1239         return selectionColor;
1240     }
1241 
1242     /**
1243      * Sets the current color used to render the selection.
1244      * Setting the color to <code>null</code> is the same as setting
1245      * <code>Color.white</code>.  Setting the color results in a
1246      * PropertyChange event ("selectionColor").
1247      *
1248      * @param c the color
1249      * @see #getSelectionColor
1250      * @beaninfo
1251      *  description: color used to render selection background
1252      *        bound: true
1253      *    preferred: true
1254      */


1255     public void setSelectionColor(Color c) {
1256         Color old = selectionColor;
1257         selectionColor = c;
1258         firePropertyChange("selectionColor", old, selectionColor);
1259     }
1260 
1261     /**
1262      * Fetches the current color used to render the
1263      * selected text.
1264      *
1265      * @return the color
1266      */
1267     public Color getSelectedTextColor() {
1268         return selectedTextColor;
1269     }
1270 
1271     /**
1272      * Sets the current color used to render the selected text.
1273      * Setting the color to <code>null</code> is the same as
1274      * <code>Color.black</code>. Setting the color results in a
1275      * PropertyChange event ("selectedTextColor") being fired.
1276      *
1277      * @param c the color
1278      * @see #getSelectedTextColor
1279      * @beaninfo
1280      *  description: color used to render selected text
1281      *        bound: true
1282      *    preferred: true
1283      */


1284     public void setSelectedTextColor(Color c) {
1285         Color old = selectedTextColor;
1286         selectedTextColor = c;
1287         firePropertyChange("selectedTextColor", old, selectedTextColor);
1288     }
1289 
1290     /**
1291      * Fetches the current color used to render the
1292      * disabled text.
1293      *
1294      * @return the color
1295      */
1296     public Color getDisabledTextColor() {
1297         return disabledTextColor;
1298     }
1299 
1300     /**
1301      * Sets the current color used to render the
1302      * disabled text.  Setting the color fires off a
1303      * PropertyChange event ("disabledTextColor").
1304      *
1305      * @param c the color
1306      * @see #getDisabledTextColor
1307      * @beaninfo
1308      *  description: color used to render disabled text
1309      *        bound: true
1310      *    preferred: true
1311      */


1312     public void setDisabledTextColor(Color c) {
1313         Color old = disabledTextColor;
1314         disabledTextColor = c;
1315         firePropertyChange("disabledTextColor", old, disabledTextColor);
1316     }
1317 
1318     /**
1319      * Replaces the currently selected content with new content
1320      * represented by the given string.  If there is no selection
1321      * this amounts to an insert of the given text.  If there
1322      * is no replacement text this amounts to a removal of the
1323      * current selection.
1324      * <p>
1325      * This is the method that is used by the default implementation
1326      * of the action for inserting content that gets bound to the
1327      * keymap actions.
1328      *
1329      * @param content  the content to replace the selection with
1330      */
1331     public void replaceSelection(String content) {


1516 
1517     /**
1518      * The bound property name for the focus accelerator.
1519      */
1520     public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
1521 
1522     /**
1523      * Sets the key accelerator that will cause the receiving text
1524      * component to get the focus.  The accelerator will be the
1525      * key combination of the platform-specific modifier key and
1526      * the character given (converted to upper case).  For example,
1527      * the ALT key is used as a modifier on Windows and the CTRL+ALT
1528      * combination is used on Mac.  By default, there is no focus
1529      * accelerator key.  Any previous key accelerator setting will be
1530      * superseded.  A '\0' key setting will be registered, and has the
1531      * effect of turning off the focus accelerator.  When the new key
1532      * is set, a PropertyChange event (FOCUS_ACCELERATOR_KEY) will be fired.
1533      *
1534      * @param aKey the key
1535      * @see #getFocusAccelerator
1536      * @beaninfo
1537      *  description: accelerator character used to grab focus
1538      *        bound: true
1539      */


1540     public void setFocusAccelerator(char aKey) {
1541         aKey = Character.toUpperCase(aKey);
1542         char old = focusAccelerator;
1543         focusAccelerator = aKey;
1544         // Fix for 4341002: value of FOCUS_ACCELERATOR_KEY is wrong.
1545         // So we fire both FOCUS_ACCELERATOR_KEY, for compatibility,
1546         // and the correct event here.
1547         firePropertyChange(FOCUS_ACCELERATOR_KEY, old, focusAccelerator);
1548         firePropertyChange("focusAccelerator", old, focusAccelerator);
1549     }
1550 
1551     /**
1552      * Returns the key accelerator that will cause the receiving
1553      * text component to get the focus.  Return '\0' if no focus
1554      * accelerator has been set.
1555      *
1556      * @return the key
1557      */
1558     public char getFocusAccelerator() {
1559         return focusAccelerator;


1613         super.removeNotify();
1614         if (getFocusedComponent() == this) {
1615             AppContext.getAppContext().remove(FOCUSED_COMPONENT);
1616         }
1617     }
1618 
1619     // --- java.awt.TextComponent methods ------------------------
1620 
1621     /**
1622      * Sets the position of the text insertion caret for the
1623      * <code>TextComponent</code>.  Note that the caret tracks change,
1624      * so this may move if the underlying text of the component is changed.
1625      * If the document is <code>null</code>, does nothing. The position
1626      * must be between 0 and the length of the component's text or else
1627      * an exception is thrown.
1628      *
1629      * @param position the position
1630      * @exception    IllegalArgumentException if the value supplied
1631      *               for <code>position</code> is less than zero or greater
1632      *               than the component's text length
1633      * @beaninfo
1634      * description: the caret position
1635      */


1636     public void setCaretPosition(int position) {
1637         Document doc = getDocument();
1638         if (doc != null) {
1639             if (position > doc.getLength() || position < 0) {
1640                 throw new IllegalArgumentException("bad position: " + position);
1641             }
1642             caret.setDot(position);
1643         }
1644     }
1645 
1646     /**
1647      * Returns the position of the text insertion caret for the
1648      * text component.
1649      *
1650      * @return the position of the text insertion caret for the
1651      *  text component &ge; 0
1652      */
1653     @Transient
1654     public int getCaretPosition() {
1655         return caret.getDot();
1656     }
1657 
1658     /**
1659      * Sets the text of this <code>TextComponent</code>
1660      * to the specified text.  If the text is <code>null</code>
1661      * or empty, has the effect of simply deleting the old text.
1662      * When text has been inserted, the resulting caret location
1663      * is determined by the implementation of the caret class.
1664      *
1665      * <p>
1666      * Note that text is not a bound property, so no <code>PropertyChangeEvent
1667      * </code> is fired when it changes. To listen for changes to the text,
1668      * use <code>DocumentListener</code>.
1669      *
1670      * @param t the new text to be set
1671      * @see #getText
1672      * @see DefaultCaret
1673      * @beaninfo
1674      * description: the text of this component
1675      */


1676     public void setText(String t) {
1677         try {
1678             Document doc = getDocument();
1679             if (doc instanceof AbstractDocument) {
1680                 ((AbstractDocument)doc).replace(0, doc.getLength(), t,null);
1681             }
1682             else {
1683                 doc.remove(0, doc.getLength());
1684                 doc.insertString(0, t, null);
1685             }
1686         } catch (BadLocationException e) {
1687             UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this);
1688         }
1689     }
1690 
1691     /**
1692      * Returns the text contained in this <code>TextComponent</code>.
1693      * If the underlying document is <code>null</code>,
1694      * will give a <code>NullPointerException</code>.
1695      *


1705         Document doc = getDocument();
1706         String txt;
1707         try {
1708             txt = doc.getText(0, doc.getLength());
1709         } catch (BadLocationException e) {
1710             txt = null;
1711         }
1712         return txt;
1713     }
1714 
1715     /**
1716      * Returns the selected text contained in this
1717      * <code>TextComponent</code>.  If the selection is
1718      * <code>null</code> or the document empty, returns <code>null</code>.
1719      *
1720      * @return the text
1721      * @exception IllegalArgumentException if the selection doesn't
1722      *  have a valid mapping into the document for some reason
1723      * @see #setText
1724      */

1725     public String getSelectedText() {
1726         String txt = null;
1727         int p0 = Math.min(caret.getDot(), caret.getMark());
1728         int p1 = Math.max(caret.getDot(), caret.getMark());
1729         if (p0 != p1) {
1730             try {
1731                 Document doc = getDocument();
1732                 txt = doc.getText(p0, p1 - p0);
1733             } catch (BadLocationException e) {
1734                 throw new IllegalArgumentException(e.getMessage());
1735             }
1736         }
1737         return txt;
1738     }
1739 
1740     /**
1741      * Returns the boolean indicating whether this
1742      * <code>TextComponent</code> is editable or not.
1743      *
1744      * @return the boolean value
1745      * @see #setEditable
1746      */
1747     public boolean isEditable() {
1748         return editable;
1749     }
1750 
1751     /**
1752      * Sets the specified boolean to indicate whether or not this
1753      * <code>TextComponent</code> should be editable.
1754      * A PropertyChange event ("editable") is fired when the
1755      * state is changed.
1756      *
1757      * @param b the boolean to be set
1758      * @see #isEditable
1759      * @beaninfo
1760      * description: specifies if the text can be edited
1761      *       bound: true
1762      */


1763     public void setEditable(boolean b) {
1764         if (b != editable) {
1765             boolean oldVal = editable;
1766             editable = b;
1767             enableInputMethods(editable);
1768             firePropertyChange("editable", Boolean.valueOf(oldVal), Boolean.valueOf(editable));
1769             repaint();
1770         }
1771     }
1772 
1773     /**
1774      * Returns the selected text's start position.  Return 0 for an
1775      * empty document, or the value of dot if no selection.
1776      *
1777      * @return the start position &ge; 0
1778      */
1779     @Transient
1780     public int getSelectionStart() {
1781         int start = Math.min(caret.getDot(), caret.getMark());
1782         return start;
1783     }
1784 
1785     /**
1786      * Sets the selection start to the specified position.  The new
1787      * starting point is constrained to be before or at the current
1788      * selection end.
1789      * <p>
1790      * This is available for backward compatibility to code
1791      * that called this method on <code>java.awt.TextComponent</code>.
1792      * This is implemented to forward to the <code>Caret</code>
1793      * implementation which is where the actual selection is maintained.
1794      *
1795      * @param selectionStart the start position of the text &ge; 0
1796      * @beaninfo
1797      * description: starting location of the selection.
1798      */


1799     public void setSelectionStart(int selectionStart) {
1800         /* Route through select method to enforce consistent policy
1801          * between selectionStart and selectionEnd.
1802          */
1803         select(selectionStart, getSelectionEnd());
1804     }
1805 
1806     /**
1807      * Returns the selected text's end position.  Return 0 if the document
1808      * is empty, or the value of dot if there is no selection.
1809      *
1810      * @return the end position &ge; 0
1811      */
1812     @Transient
1813     public int getSelectionEnd() {
1814         int end = Math.max(caret.getDot(), caret.getMark());
1815         return end;
1816     }
1817 
1818     /**
1819      * Sets the selection end to the specified position.  The new
1820      * end point is constrained to be at or after the current
1821      * selection start.
1822      * <p>
1823      * This is available for backward compatibility to code
1824      * that called this method on <code>java.awt.TextComponent</code>.
1825      * This is implemented to forward to the <code>Caret</code>
1826      * implementation which is where the actual selection is maintained.
1827      *
1828      * @param selectionEnd the end position of the text &ge; 0
1829      * @beaninfo
1830      * description: ending location of the selection.
1831      */


1832     public void setSelectionEnd(int selectionEnd) {
1833         /* Route through select method to enforce consistent policy
1834          * between selectionStart and selectionEnd.
1835          */
1836         select(getSelectionStart(), selectionEnd);
1837     }
1838 
1839     /**
1840      * Selects the text between the specified start and end positions.
1841      * <p>
1842      * This method sets the start and end positions of the
1843      * selected text, enforcing the restriction that the start position
1844      * must be greater than or equal to zero.  The end position must be
1845      * greater than or equal to the start position, and less than or
1846      * equal to the length of the text component's text.
1847      * <p>
1848      * If the caller supplies values that are inconsistent or out of
1849      * bounds, the method enforces these constraints silently, and
1850      * without failure. Specifically, if the start position or end
1851      * position is greater than the length of the text, it is reset to


1927         if (retValue == null) {
1928             TextUI ui = getUI();
1929             if (ui != null) {
1930                 retValue = ui.getToolTipText(this, new Point(event.getX(),
1931                                                              event.getY()));
1932             }
1933         }
1934         return retValue;
1935     }
1936 
1937     // --- Scrollable methods ---------------------------------------------
1938 
1939     /**
1940      * Returns the preferred size of the viewport for a view component.
1941      * This is implemented to do the default behavior of returning
1942      * the preferred size of the component.
1943      *
1944      * @return the <code>preferredSize</code> of a <code>JViewport</code>
1945      * whose view is this <code>Scrollable</code>
1946      */

1947     public Dimension getPreferredScrollableViewportSize() {
1948         return getPreferredSize();
1949     }
1950 
1951 
1952     /**
1953      * Components that display logical rows or columns should compute
1954      * the scroll increment that will completely expose one new row
1955      * or column, depending on the value of orientation.  Ideally,
1956      * components should handle a partially exposed row or column by
1957      * returning the distance required to completely expose the item.
1958      * <p>
1959      * The default implementation of this is to simply return 10% of
1960      * the visible area.  Subclasses are likely to be able to provide
1961      * a much more reasonable value.
1962      *
1963      * @param visibleRect the view area visible within the viewport
1964      * @param orientation either <code>SwingConstants.VERTICAL</code> or
1965      *   <code>SwingConstants.HORIZONTAL</code>
1966      * @param direction less than zero to scroll up/left, greater than


2010         }
2011     }
2012 
2013 
2014     /**
2015      * Returns true if a viewport should always force the width of this
2016      * <code>Scrollable</code> to match the width of the viewport.
2017      * For example a normal text view that supported line wrapping
2018      * would return true here, since it would be undesirable for
2019      * wrapped lines to disappear beyond the right
2020      * edge of the viewport.  Note that returning true for a
2021      * <code>Scrollable</code> whose ancestor is a <code>JScrollPane</code>
2022      * effectively disables horizontal scrolling.
2023      * <p>
2024      * Scrolling containers, like <code>JViewport</code>,
2025      * will use this method each time they are validated.
2026      *
2027      * @return true if a viewport should force the <code>Scrollable</code>s
2028      *   width to match its own
2029      */

2030     public boolean getScrollableTracksViewportWidth() {
2031         Container parent = SwingUtilities.getUnwrappedParent(this);
2032         if (parent instanceof JViewport) {
2033             return parent.getWidth() > getPreferredSize().width;
2034         }
2035         return false;
2036     }
2037 
2038     /**
2039      * Returns true if a viewport should always force the height of this
2040      * <code>Scrollable</code> to match the height of the viewport.
2041      * For example a columnar text view that flowed text in left to
2042      * right columns could effectively disable vertical scrolling by
2043      * returning true here.
2044      * <p>
2045      * Scrolling containers, like <code>JViewport</code>,
2046      * will use this method each time they are validated.
2047      *
2048      * @return true if a viewport should force the Scrollables height
2049      *   to match its own
2050      */

2051     public boolean getScrollableTracksViewportHeight() {
2052         Container parent = SwingUtilities.getUnwrappedParent(this);
2053         if (parent instanceof JViewport) {
2054             return parent.getHeight() > getPreferredSize().height;
2055         }
2056         return false;
2057     }
2058 
2059 
2060 //////////////////
2061 // Printing Support
2062 //////////////////
2063 
2064     /**
2065      * A convenience print method that displays a print dialog, and then
2066      * prints this {@code JTextComponent} in <i>interactive</i> mode with no
2067      * header or footer text. Note: this method
2068      * blocks until printing is done.
2069      * <p>
2070      * Note: In <i>headless</i> mode, no dialogs will be shown.


2465     }
2466 
2467 
2468 /////////////////
2469 // Accessibility support
2470 ////////////////
2471 
2472 
2473     /**
2474      * Gets the <code>AccessibleContext</code> associated with this
2475      * <code>JTextComponent</code>. For text components,
2476      * the <code>AccessibleContext</code> takes the form of an
2477      * <code>AccessibleJTextComponent</code>.
2478      * A new <code>AccessibleJTextComponent</code> instance
2479      * is created if necessary.
2480      *
2481      * @return an <code>AccessibleJTextComponent</code> that serves as the
2482      *         <code>AccessibleContext</code> of this
2483      *         <code>JTextComponent</code>
2484      */

2485     public AccessibleContext getAccessibleContext() {
2486         if (accessibleContext == null) {
2487             accessibleContext = new AccessibleJTextComponent();
2488         }
2489         return accessibleContext;
2490     }
2491 
2492     /**
2493      * This class implements accessibility support for the
2494      * <code>JTextComponent</code> class.  It provides an implementation of
2495      * the Java Accessibility API appropriate to menu user-interface elements.
2496      * <p>
2497      * <strong>Warning:</strong>
2498      * Serialized objects of this class will not be compatible with
2499      * future Swing releases. The current serialization support is
2500      * appropriate for short term storage or RMI between applications running
2501      * the same version of Swing.  As of 1.4, support for long term storage
2502      * of all JavaBeans&trade;
2503      * has been added to the <code>java.beans</code> package.
2504      * Please see {@link java.beans.XMLEncoder}.


4520             } else {
4521                 switch (e.getID()) {
4522                 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4523                     replaceInputMethodText(e);
4524 
4525                     // fall through
4526 
4527                 case InputMethodEvent.CARET_POSITION_CHANGED:
4528                     setInputMethodCaretPosition(e);
4529                     break;
4530                 }
4531             }
4532 
4533             e.consume();
4534         }
4535     }
4536 
4537     //
4538     // Overrides this method to become an active input method client.
4539     //

4540     public InputMethodRequests getInputMethodRequests() {
4541         if (inputMethodRequestsHandler == null) {
4542             inputMethodRequestsHandler = new InputMethodRequestsHandler();
4543             Document doc = getDocument();
4544             if (doc != null) {
4545                 doc.addDocumentListener((DocumentListener)inputMethodRequestsHandler);
4546             }
4547         }
4548 
4549         return inputMethodRequestsHandler;
4550     }
4551 
4552     //
4553     // Overrides this method to watch the listener installed.
4554     //
4555     public void addInputMethodListener(InputMethodListener l) {
4556         super.addInputMethodListener(l);
4557         if (l != null) {
4558             needToSendKeyTypedEvent = false;
4559             checkedInputOverride = true;




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing.text;
  26 
  27 import com.sun.beans.util.Cache;
  28 
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 
  32 import java.beans.JavaBean;
  33 import java.beans.BeanProperty;
  34 import java.beans.Transient;
  35 import java.util.HashMap;
  36 import java.util.Hashtable;
  37 import java.util.Enumeration;
  38 import java.util.Vector;
  39 
  40 import java.util.concurrent.*;
  41 
  42 import java.io.*;
  43 
  44 import java.awt.*;
  45 import java.awt.event.*;
  46 import java.awt.print.*;
  47 import java.awt.datatransfer.*;
  48 import java.awt.im.InputContext;
  49 import java.awt.im.InputMethodRequests;
  50 import java.awt.font.TextHitInfo;
  51 import java.awt.font.TextAttribute;
  52 
  53 import java.awt.print.Printable;
  54 import java.awt.print.PrinterException;
  55 
  56 import javax.print.PrintService;
  57 import javax.print.attribute.PrintRequestAttributeSet;
  58 
  59 import java.text.*;
  60 import java.text.AttributedCharacterIterator.Attribute;
  61 
  62 import javax.swing.*;
  63 import javax.swing.event.*;
  64 import javax.swing.plaf.*;
  65 
  66 import javax.accessibility.*;
  67 
  68 import javax.print.attribute.*;
  69 
  70 import sun.awt.AppContext;
  71 

  72 import sun.swing.PrintingStatus;
  73 import sun.swing.SwingUtilities2;
  74 import sun.swing.text.TextComponentPrintable;
  75 import sun.swing.SwingAccessor;
  76 
  77 /**
  78  * <code>JTextComponent</code> is the base class for swing text
  79  * components.  It tries to be compatible with the
  80  * <code>java.awt.TextComponent</code> class
  81  * where it can reasonably do so.  Also provided are other services
  82  * for additional flexibility (beyond the pluggable UI and bean
  83  * support).
  84  * You can find information on how to use the functionality
  85  * this class provides in
  86  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html">General Rules for Using Text Components</a>,
  87  * a section in <em>The Java Tutorial.</em>
  88  *
  89  * <dl>
  90  * <dt><b>Caret Changes</b>
  91  * <dd>


 259  * <a href="DefaultEditorKit.html">DefaultEditorKit</a>.
 260  *
 261  *
 262  * <dt><b>Printing support</b>
 263  * <dd>
 264  * Several {@link #print print} methods are provided for basic
 265  * document printing.  If more advanced printing is needed, use the
 266  * {@link #getPrintable} method.
 267  * </dl>
 268  *
 269  * <p>
 270  * <strong>Warning:</strong>
 271  * Serialized objects of this class will not be compatible with
 272  * future Swing releases. The current serialization support is
 273  * appropriate for short term storage or RMI between applications running
 274  * the same version of Swing.  As of 1.4, support for long term storage
 275  * of all JavaBeans&trade;
 276  * has been added to the <code>java.beans</code> package.
 277  * Please see {@link java.beans.XMLEncoder}.
 278  *



 279  * @author  Timothy Prinzing
 280  * @author Igor Kushnirskiy (printing support)
 281  * @see Document
 282  * @see DocumentEvent
 283  * @see DocumentListener
 284  * @see Caret
 285  * @see CaretEvent
 286  * @see CaretListener
 287  * @see TextUI
 288  * @see View
 289  * @see ViewFactory
 290  */
 291 @JavaBean(defaultProperty = "UI")
 292 @SwingContainer(false)
 293 @SuppressWarnings("serial") // Same-version serialization only
 294 public abstract class JTextComponent extends JComponent implements Scrollable, Accessible
 295 {
 296     /**
 297      * Creates a new <code>JTextComponent</code>.
 298      * Listeners for caret events are established, and the pluggable
 299      * UI installed.  The component is marked as editable.  No layout manager
 300      * is used, because layout is managed by the view subsystem of text.
 301      * The document model is set to <code>null</code>.
 302      */
 303     public JTextComponent() {
 304         super();
 305         // enable InputMethodEvent for on-the-spot pre-editing
 306         enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK);
 307         caretEvent = new MutableCaretEvent(this);
 308         addMouseListener(caretEvent);
 309         addFocusListener(caretEvent);
 310         setEditable(true);
 311         setDragEnabled(false);
 312         setLayout(null); // layout is managed by View hierarchy


 357      * @param listener the listener to be removed
 358      * @see javax.swing.event.CaretEvent
 359      */
 360     public void removeCaretListener(CaretListener listener) {
 361         listenerList.remove(CaretListener.class, listener);
 362     }
 363 
 364     /**
 365      * Returns an array of all the caret listeners
 366      * registered on this text component.
 367      *
 368      * @return all of this component's <code>CaretListener</code>s
 369      *         or an empty
 370      *         array if no caret listeners are currently registered
 371      *
 372      * @see #addCaretListener
 373      * @see #removeCaretListener
 374      *
 375      * @since 1.4
 376      */
 377     @BeanProperty(bound = false)
 378     public CaretListener[] getCaretListeners() {
 379         return listenerList.getListeners(CaretListener.class);
 380     }
 381 
 382     /**
 383      * Notifies all listeners that have registered interest for
 384      * notification on this event type.  The event instance
 385      * is lazily created using the parameters passed into
 386      * the fire method.  The listener list is processed in a
 387      * last-to-first manner.
 388      *
 389      * @param e the event
 390      * @see EventListenerList
 391      */
 392     protected void fireCaretUpdate(CaretEvent e) {
 393         // Guaranteed to return a non-null array
 394         Object[] listeners = listenerList.getListenerList();
 395         // Process the listeners last to first, notifying
 396         // those that are interested in this event
 397         for (int i = listeners.length-2; i>=0; i-=2) {
 398             if (listeners[i]==CaretListener.class) {
 399                 ((CaretListener)listeners[i+1]).caretUpdate(e);
 400             }
 401         }
 402     }
 403 
 404     /**
 405      * Associates the editor with a text document.
 406      * The currently registered factory is used to build a view for
 407      * the document, which gets displayed by the editor after revalidation.
 408      * A PropertyChange event ("document") is propagated to each listener.
 409      *
 410      * @param doc  the document to display/edit
 411      * @see #getDocument




 412      */
 413     @BeanProperty(expert = true, description
 414             = "the text document model")
 415     public void setDocument(Document doc) {
 416         Document old = model;
 417 
 418         /*
 419          * acquire a read lock on the old model to prevent notification of
 420          * mutations while we disconnecting the old model.
 421          */
 422         try {
 423             if (old instanceof AbstractDocument) {
 424                 ((AbstractDocument)old).readLock();
 425             }
 426             if (accessibleContext != null) {
 427                 model.removeDocumentListener(
 428                     ((AccessibleJTextComponent)accessibleContext));
 429             }
 430             if (inputMethodRequestsHandler != null) {
 431                 model.removeDocumentListener((DocumentListener)inputMethodRequestsHandler);
 432             }
 433             model = doc;
 434 


 477         // ComponentOrientation property.
 478         Document doc = getDocument();
 479         if( doc !=  null ) {
 480             Boolean runDir = o.isLeftToRight()
 481                              ? TextAttribute.RUN_DIRECTION_LTR
 482                              : TextAttribute.RUN_DIRECTION_RTL;
 483             doc.putProperty( TextAttribute.RUN_DIRECTION, runDir );
 484         }
 485         super.setComponentOrientation( o );
 486     }
 487 
 488     /**
 489      * Fetches the command list for the editor.  This is
 490      * the list of commands supported by the plugged-in UI
 491      * augmented by the collection of commands that the
 492      * editor itself supports.  These are useful for binding
 493      * to events, such as in a keymap.
 494      *
 495      * @return the command list
 496      */
 497     @BeanProperty(bound = false)
 498     public Action[] getActions() {
 499         return getUI().getEditorKit(this).getActions();
 500     }
 501 
 502     /**
 503      * Sets margin space between the text component's border
 504      * and its text.  The text component's default <code>Border</code>
 505      * object will use this value to create the proper margin.
 506      * However, if a non-default border is set on the text component,
 507      * it is that <code>Border</code> object's responsibility to create the
 508      * appropriate margin space (else this property will effectively
 509      * be ignored).  This causes a redraw of the component.
 510      * A PropertyChange event ("margin") is sent to all listeners.
 511      *
 512      * @param m the space between the border and the text



 513      */
 514     @BeanProperty(description
 515             = "desired space between the border and text area")
 516     public void setMargin(Insets m) {
 517         Insets old = margin;
 518         margin = m;
 519         firePropertyChange("margin", old, m);
 520         invalidate();
 521     }
 522 
 523     /**
 524      * Returns the margin between the text component's border and
 525      * its text.
 526      *
 527      * @return the margin
 528      */
 529     public Insets getMargin() {
 530         return margin;
 531     }
 532 
 533     /**
 534      * Sets the <code>NavigationFilter</code>. <code>NavigationFilter</code>
 535      * is used by <code>DefaultCaret</code> and the default cursor movement


 556 
 557     /**
 558      * Fetches the caret that allows text-oriented navigation over
 559      * the view.
 560      *
 561      * @return the caret
 562      */
 563     @Transient
 564     public Caret getCaret() {
 565         return caret;
 566     }
 567 
 568     /**
 569      * Sets the caret to be used.  By default this will be set
 570      * by the UI that gets installed.  This can be changed to
 571      * a custom caret if desired.  Setting the caret results in a
 572      * PropertyChange event ("caret") being fired.
 573      *
 574      * @param c the caret
 575      * @see #getCaret




 576      */
 577     @BeanProperty(expert = true, description
 578             = "the caret used to select/navigate")
 579     public void setCaret(Caret c) {
 580         if (caret != null) {
 581             caret.removeChangeListener(caretEvent);
 582             caret.deinstall(this);
 583         }
 584         Caret old = caret;
 585         caret = c;
 586         if (caret != null) {
 587             caret.install(this);
 588             caret.addChangeListener(caretEvent);
 589         }
 590         firePropertyChange("caret", old, caret);
 591     }
 592 
 593     /**
 594      * Fetches the object responsible for making highlights.
 595      *
 596      * @return the highlighter
 597      */
 598     public Highlighter getHighlighter() {
 599         return highlighter;
 600     }
 601 
 602     /**
 603      * Sets the highlighter to be used.  By default this will be set
 604      * by the UI that gets installed.  This can be changed to
 605      * a custom highlighter if desired.  The highlighter can be set to
 606      * <code>null</code> to disable it.
 607      * A PropertyChange event ("highlighter") is fired
 608      * when a new highlighter is installed.
 609      *
 610      * @param h the highlighter
 611      * @see #getHighlighter




 612      */
 613     @BeanProperty(expert = true, description
 614             = "object responsible for background highlights")
 615     public void setHighlighter(Highlighter h) {
 616         if (highlighter != null) {
 617             highlighter.deinstall(this);
 618         }
 619         Highlighter old = highlighter;
 620         highlighter = h;
 621         if (highlighter != null) {
 622             highlighter.install(this);
 623         }
 624         firePropertyChange("highlighter", old, h);
 625     }
 626 
 627     /**
 628      * Sets the keymap to use for binding events to
 629      * actions.  Setting to <code>null</code> effectively disables
 630      * keyboard input.
 631      * A PropertyChange event ("keymap") is fired when a new keymap
 632      * is installed.
 633      *
 634      * @param map the keymap
 635      * @see #getKeymap



 636      */
 637     @BeanProperty(description
 638             = "set of key event to action bindings to use")
 639     public void setKeymap(Keymap map) {
 640         Keymap old = keymap;
 641         keymap = map;
 642         firePropertyChange("keymap", old, keymap);
 643         updateInputMap(old, map);
 644     }
 645 
 646     /**
 647      * Turns on or off automatic drag handling. In order to enable automatic
 648      * drag handling, this property should be set to {@code true}, and the
 649      * component's {@code TransferHandler} needs to be {@code non-null}.
 650      * The default value of the {@code dragEnabled} property is {@code false}.
 651      * <p>
 652      * The job of honoring this property, and recognizing a user drag gesture,
 653      * lies with the look and feel implementation, and in particular, the component's
 654      * {@code TextUI}. When automatic drag handling is enabled, most look and
 655      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
 656      * drag and drop operation whenever the user presses the mouse button over
 657      * a selection and then moves the mouse a few pixels. Setting this property to
 658      * {@code true} can therefore have a subtle effect on how selections behave.
 659      * <p>
 660      * If a look and feel is used that ignores this property, you can still
 661      * begin a drag and drop operation by calling {@code exportAsDrag} on the
 662      * component's {@code TransferHandler}.
 663      *
 664      * @param b whether or not to enable automatic drag handling
 665      * @exception HeadlessException if
 666      *            <code>b</code> is <code>true</code> and
 667      *            <code>GraphicsEnvironment.isHeadless()</code>
 668      *            returns <code>true</code>
 669      * @see java.awt.GraphicsEnvironment#isHeadless
 670      * @see #getDragEnabled
 671      * @see #setTransferHandler
 672      * @see TransferHandler
 673      * @since 1.4




 674      */
 675     @BeanProperty(bound = false, description
 676             = "determines whether automatic drag handling is enabled")
 677     public void setDragEnabled(boolean b) {
 678         checkDragEnabled(b);
 679         dragEnabled = b;
 680     }
 681 
 682     private static void checkDragEnabled(boolean b) {
 683         if (b && GraphicsEnvironment.isHeadless()) {
 684             throw new HeadlessException();
 685         }
 686     }
 687 
 688     /**
 689      * Returns whether or not automatic drag handling is enabled.
 690      *
 691      * @return the value of the {@code dragEnabled} property
 692      * @see #setDragEnabled
 693      * @since 1.4
 694      */
 695     public boolean getDragEnabled() {
 696         return dragEnabled;


 928     }
 929 
 930     /**
 931      * Returns the location that this component should visually indicate
 932      * as the drop location during a DnD operation over the component,
 933      * or {@code null} if no location is to currently be shown.
 934      * <p>
 935      * This method is not meant for querying the drop location
 936      * from a {@code TransferHandler}, as the drop location is only
 937      * set after the {@code TransferHandler}'s <code>canImport</code>
 938      * has returned and has allowed for the location to be shown.
 939      * <p>
 940      * When this property changes, a property change event with
 941      * name "dropLocation" is fired by the component.
 942      *
 943      * @return the drop location
 944      * @see #setDropMode
 945      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
 946      * @since 1.6
 947      */
 948     @BeanProperty(bound = false)
 949     public final DropLocation getDropLocation() {
 950         return dropLocation;
 951     }
 952 
 953 
 954     /**
 955      * Updates the <code>InputMap</code>s in response to a
 956      * <code>Keymap</code> change.
 957      * @param oldKm  the old <code>Keymap</code>
 958      * @param newKm  the new <code>Keymap</code>
 959      */
 960     void updateInputMap(Keymap oldKm, Keymap newKm) {
 961         // Locate the current KeymapWrapper.
 962         InputMap km = getInputMap(JComponent.WHEN_FOCUSED);
 963         InputMap last = km;
 964         while (km != null && !(km instanceof KeymapWrapper)) {
 965             last = km;
 966             km = km.getParent();
 967         }
 968         if (km != null) {


1194     }
1195 
1196     /**
1197      * Fetches the current color used to render the
1198      * caret.
1199      *
1200      * @return the color
1201      */
1202     public Color getCaretColor() {
1203         return caretColor;
1204     }
1205 
1206     /**
1207      * Sets the current color used to render the caret.
1208      * Setting to <code>null</code> effectively restores the default color.
1209      * Setting the color results in a PropertyChange event ("caretColor")
1210      * being fired.
1211      *
1212      * @param c the color
1213      * @see #getCaretColor




1214      */
1215     @BeanProperty(preferred = true, description
1216             = "the color used to render the caret")
1217     public void setCaretColor(Color c) {
1218         Color old = caretColor;
1219         caretColor = c;
1220         firePropertyChange("caretColor", old, caretColor);
1221     }
1222 
1223     /**
1224      * Fetches the current color used to render the
1225      * selection.
1226      *
1227      * @return the color
1228      */
1229     public Color getSelectionColor() {
1230         return selectionColor;
1231     }
1232 
1233     /**
1234      * Sets the current color used to render the selection.
1235      * Setting the color to <code>null</code> is the same as setting
1236      * <code>Color.white</code>.  Setting the color results in a
1237      * PropertyChange event ("selectionColor").
1238      *
1239      * @param c the color
1240      * @see #getSelectionColor




1241      */
1242     @BeanProperty(preferred = true, description
1243             = "color used to render selection background")
1244     public void setSelectionColor(Color c) {
1245         Color old = selectionColor;
1246         selectionColor = c;
1247         firePropertyChange("selectionColor", old, selectionColor);
1248     }
1249 
1250     /**
1251      * Fetches the current color used to render the
1252      * selected text.
1253      *
1254      * @return the color
1255      */
1256     public Color getSelectedTextColor() {
1257         return selectedTextColor;
1258     }
1259 
1260     /**
1261      * Sets the current color used to render the selected text.
1262      * Setting the color to <code>null</code> is the same as
1263      * <code>Color.black</code>. Setting the color results in a
1264      * PropertyChange event ("selectedTextColor") being fired.
1265      *
1266      * @param c the color
1267      * @see #getSelectedTextColor




1268      */
1269     @BeanProperty(preferred = true, description
1270             = "color used to render selected text")
1271     public void setSelectedTextColor(Color c) {
1272         Color old = selectedTextColor;
1273         selectedTextColor = c;
1274         firePropertyChange("selectedTextColor", old, selectedTextColor);
1275     }
1276 
1277     /**
1278      * Fetches the current color used to render the
1279      * disabled text.
1280      *
1281      * @return the color
1282      */
1283     public Color getDisabledTextColor() {
1284         return disabledTextColor;
1285     }
1286 
1287     /**
1288      * Sets the current color used to render the
1289      * disabled text.  Setting the color fires off a
1290      * PropertyChange event ("disabledTextColor").
1291      *
1292      * @param c the color
1293      * @see #getDisabledTextColor




1294      */
1295     @BeanProperty(preferred = true, description
1296             = "color used to render disabled text")
1297     public void setDisabledTextColor(Color c) {
1298         Color old = disabledTextColor;
1299         disabledTextColor = c;
1300         firePropertyChange("disabledTextColor", old, disabledTextColor);
1301     }
1302 
1303     /**
1304      * Replaces the currently selected content with new content
1305      * represented by the given string.  If there is no selection
1306      * this amounts to an insert of the given text.  If there
1307      * is no replacement text this amounts to a removal of the
1308      * current selection.
1309      * <p>
1310      * This is the method that is used by the default implementation
1311      * of the action for inserting content that gets bound to the
1312      * keymap actions.
1313      *
1314      * @param content  the content to replace the selection with
1315      */
1316     public void replaceSelection(String content) {


1501 
1502     /**
1503      * The bound property name for the focus accelerator.
1504      */
1505     public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
1506 
1507     /**
1508      * Sets the key accelerator that will cause the receiving text
1509      * component to get the focus.  The accelerator will be the
1510      * key combination of the platform-specific modifier key and
1511      * the character given (converted to upper case).  For example,
1512      * the ALT key is used as a modifier on Windows and the CTRL+ALT
1513      * combination is used on Mac.  By default, there is no focus
1514      * accelerator key.  Any previous key accelerator setting will be
1515      * superseded.  A '\0' key setting will be registered, and has the
1516      * effect of turning off the focus accelerator.  When the new key
1517      * is set, a PropertyChange event (FOCUS_ACCELERATOR_KEY) will be fired.
1518      *
1519      * @param aKey the key
1520      * @see #getFocusAccelerator



1521      */
1522     @BeanProperty(description
1523             = "accelerator character used to grab focus")
1524     public void setFocusAccelerator(char aKey) {
1525         aKey = Character.toUpperCase(aKey);
1526         char old = focusAccelerator;
1527         focusAccelerator = aKey;
1528         // Fix for 4341002: value of FOCUS_ACCELERATOR_KEY is wrong.
1529         // So we fire both FOCUS_ACCELERATOR_KEY, for compatibility,
1530         // and the correct event here.
1531         firePropertyChange(FOCUS_ACCELERATOR_KEY, old, focusAccelerator);
1532         firePropertyChange("focusAccelerator", old, focusAccelerator);
1533     }
1534 
1535     /**
1536      * Returns the key accelerator that will cause the receiving
1537      * text component to get the focus.  Return '\0' if no focus
1538      * accelerator has been set.
1539      *
1540      * @return the key
1541      */
1542     public char getFocusAccelerator() {
1543         return focusAccelerator;


1597         super.removeNotify();
1598         if (getFocusedComponent() == this) {
1599             AppContext.getAppContext().remove(FOCUSED_COMPONENT);
1600         }
1601     }
1602 
1603     // --- java.awt.TextComponent methods ------------------------
1604 
1605     /**
1606      * Sets the position of the text insertion caret for the
1607      * <code>TextComponent</code>.  Note that the caret tracks change,
1608      * so this may move if the underlying text of the component is changed.
1609      * If the document is <code>null</code>, does nothing. The position
1610      * must be between 0 and the length of the component's text or else
1611      * an exception is thrown.
1612      *
1613      * @param position the position
1614      * @exception    IllegalArgumentException if the value supplied
1615      *               for <code>position</code> is less than zero or greater
1616      *               than the component's text length


1617      */
1618     @BeanProperty(bound = false, description
1619             = "the caret position")
1620     public void setCaretPosition(int position) {
1621         Document doc = getDocument();
1622         if (doc != null) {
1623             if (position > doc.getLength() || position < 0) {
1624                 throw new IllegalArgumentException("bad position: " + position);
1625             }
1626             caret.setDot(position);
1627         }
1628     }
1629 
1630     /**
1631      * Returns the position of the text insertion caret for the
1632      * text component.
1633      *
1634      * @return the position of the text insertion caret for the
1635      *  text component &ge; 0
1636      */
1637     @Transient
1638     public int getCaretPosition() {
1639         return caret.getDot();
1640     }
1641 
1642     /**
1643      * Sets the text of this <code>TextComponent</code>
1644      * to the specified text.  If the text is <code>null</code>
1645      * or empty, has the effect of simply deleting the old text.
1646      * When text has been inserted, the resulting caret location
1647      * is determined by the implementation of the caret class.
1648      *
1649      * <p>
1650      * Note that text is not a bound property, so no <code>PropertyChangeEvent
1651      * </code> is fired when it changes. To listen for changes to the text,
1652      * use <code>DocumentListener</code>.
1653      *
1654      * @param t the new text to be set
1655      * @see #getText
1656      * @see DefaultCaret


1657      */
1658     @BeanProperty(bound = false, description
1659             = "the text of this component")
1660     public void setText(String t) {
1661         try {
1662             Document doc = getDocument();
1663             if (doc instanceof AbstractDocument) {
1664                 ((AbstractDocument)doc).replace(0, doc.getLength(), t,null);
1665             }
1666             else {
1667                 doc.remove(0, doc.getLength());
1668                 doc.insertString(0, t, null);
1669             }
1670         } catch (BadLocationException e) {
1671             UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this);
1672         }
1673     }
1674 
1675     /**
1676      * Returns the text contained in this <code>TextComponent</code>.
1677      * If the underlying document is <code>null</code>,
1678      * will give a <code>NullPointerException</code>.
1679      *


1689         Document doc = getDocument();
1690         String txt;
1691         try {
1692             txt = doc.getText(0, doc.getLength());
1693         } catch (BadLocationException e) {
1694             txt = null;
1695         }
1696         return txt;
1697     }
1698 
1699     /**
1700      * Returns the selected text contained in this
1701      * <code>TextComponent</code>.  If the selection is
1702      * <code>null</code> or the document empty, returns <code>null</code>.
1703      *
1704      * @return the text
1705      * @exception IllegalArgumentException if the selection doesn't
1706      *  have a valid mapping into the document for some reason
1707      * @see #setText
1708      */
1709     @BeanProperty(bound = false)
1710     public String getSelectedText() {
1711         String txt = null;
1712         int p0 = Math.min(caret.getDot(), caret.getMark());
1713         int p1 = Math.max(caret.getDot(), caret.getMark());
1714         if (p0 != p1) {
1715             try {
1716                 Document doc = getDocument();
1717                 txt = doc.getText(p0, p1 - p0);
1718             } catch (BadLocationException e) {
1719                 throw new IllegalArgumentException(e.getMessage());
1720             }
1721         }
1722         return txt;
1723     }
1724 
1725     /**
1726      * Returns the boolean indicating whether this
1727      * <code>TextComponent</code> is editable or not.
1728      *
1729      * @return the boolean value
1730      * @see #setEditable
1731      */
1732     public boolean isEditable() {
1733         return editable;
1734     }
1735 
1736     /**
1737      * Sets the specified boolean to indicate whether or not this
1738      * <code>TextComponent</code> should be editable.
1739      * A PropertyChange event ("editable") is fired when the
1740      * state is changed.
1741      *
1742      * @param b the boolean to be set
1743      * @see #isEditable



1744      */
1745     @BeanProperty(description
1746             = "specifies if the text can be edited")
1747     public void setEditable(boolean b) {
1748         if (b != editable) {
1749             boolean oldVal = editable;
1750             editable = b;
1751             enableInputMethods(editable);
1752             firePropertyChange("editable", Boolean.valueOf(oldVal), Boolean.valueOf(editable));
1753             repaint();
1754         }
1755     }
1756 
1757     /**
1758      * Returns the selected text's start position.  Return 0 for an
1759      * empty document, or the value of dot if no selection.
1760      *
1761      * @return the start position &ge; 0
1762      */
1763     @Transient
1764     public int getSelectionStart() {
1765         int start = Math.min(caret.getDot(), caret.getMark());
1766         return start;
1767     }
1768 
1769     /**
1770      * Sets the selection start to the specified position.  The new
1771      * starting point is constrained to be before or at the current
1772      * selection end.
1773      * <p>
1774      * This is available for backward compatibility to code
1775      * that called this method on <code>java.awt.TextComponent</code>.
1776      * This is implemented to forward to the <code>Caret</code>
1777      * implementation which is where the actual selection is maintained.
1778      *
1779      * @param selectionStart the start position of the text &ge; 0


1780      */
1781     @BeanProperty(bound = false, description
1782             = "starting location of the selection.")
1783     public void setSelectionStart(int selectionStart) {
1784         /* Route through select method to enforce consistent policy
1785          * between selectionStart and selectionEnd.
1786          */
1787         select(selectionStart, getSelectionEnd());
1788     }
1789 
1790     /**
1791      * Returns the selected text's end position.  Return 0 if the document
1792      * is empty, or the value of dot if there is no selection.
1793      *
1794      * @return the end position &ge; 0
1795      */
1796     @Transient
1797     public int getSelectionEnd() {
1798         int end = Math.max(caret.getDot(), caret.getMark());
1799         return end;
1800     }
1801 
1802     /**
1803      * Sets the selection end to the specified position.  The new
1804      * end point is constrained to be at or after the current
1805      * selection start.
1806      * <p>
1807      * This is available for backward compatibility to code
1808      * that called this method on <code>java.awt.TextComponent</code>.
1809      * This is implemented to forward to the <code>Caret</code>
1810      * implementation which is where the actual selection is maintained.
1811      *
1812      * @param selectionEnd the end position of the text &ge; 0


1813      */
1814     @BeanProperty(bound = false, description
1815             = "ending location of the selection.")
1816     public void setSelectionEnd(int selectionEnd) {
1817         /* Route through select method to enforce consistent policy
1818          * between selectionStart and selectionEnd.
1819          */
1820         select(getSelectionStart(), selectionEnd);
1821     }
1822 
1823     /**
1824      * Selects the text between the specified start and end positions.
1825      * <p>
1826      * This method sets the start and end positions of the
1827      * selected text, enforcing the restriction that the start position
1828      * must be greater than or equal to zero.  The end position must be
1829      * greater than or equal to the start position, and less than or
1830      * equal to the length of the text component's text.
1831      * <p>
1832      * If the caller supplies values that are inconsistent or out of
1833      * bounds, the method enforces these constraints silently, and
1834      * without failure. Specifically, if the start position or end
1835      * position is greater than the length of the text, it is reset to


1911         if (retValue == null) {
1912             TextUI ui = getUI();
1913             if (ui != null) {
1914                 retValue = ui.getToolTipText(this, new Point(event.getX(),
1915                                                              event.getY()));
1916             }
1917         }
1918         return retValue;
1919     }
1920 
1921     // --- Scrollable methods ---------------------------------------------
1922 
1923     /**
1924      * Returns the preferred size of the viewport for a view component.
1925      * This is implemented to do the default behavior of returning
1926      * the preferred size of the component.
1927      *
1928      * @return the <code>preferredSize</code> of a <code>JViewport</code>
1929      * whose view is this <code>Scrollable</code>
1930      */
1931     @BeanProperty(bound = false)
1932     public Dimension getPreferredScrollableViewportSize() {
1933         return getPreferredSize();
1934     }
1935 
1936 
1937     /**
1938      * Components that display logical rows or columns should compute
1939      * the scroll increment that will completely expose one new row
1940      * or column, depending on the value of orientation.  Ideally,
1941      * components should handle a partially exposed row or column by
1942      * returning the distance required to completely expose the item.
1943      * <p>
1944      * The default implementation of this is to simply return 10% of
1945      * the visible area.  Subclasses are likely to be able to provide
1946      * a much more reasonable value.
1947      *
1948      * @param visibleRect the view area visible within the viewport
1949      * @param orientation either <code>SwingConstants.VERTICAL</code> or
1950      *   <code>SwingConstants.HORIZONTAL</code>
1951      * @param direction less than zero to scroll up/left, greater than


1995         }
1996     }
1997 
1998 
1999     /**
2000      * Returns true if a viewport should always force the width of this
2001      * <code>Scrollable</code> to match the width of the viewport.
2002      * For example a normal text view that supported line wrapping
2003      * would return true here, since it would be undesirable for
2004      * wrapped lines to disappear beyond the right
2005      * edge of the viewport.  Note that returning true for a
2006      * <code>Scrollable</code> whose ancestor is a <code>JScrollPane</code>
2007      * effectively disables horizontal scrolling.
2008      * <p>
2009      * Scrolling containers, like <code>JViewport</code>,
2010      * will use this method each time they are validated.
2011      *
2012      * @return true if a viewport should force the <code>Scrollable</code>s
2013      *   width to match its own
2014      */
2015     @BeanProperty(bound = false)
2016     public boolean getScrollableTracksViewportWidth() {
2017         Container parent = SwingUtilities.getUnwrappedParent(this);
2018         if (parent instanceof JViewport) {
2019             return parent.getWidth() > getPreferredSize().width;
2020         }
2021         return false;
2022     }
2023 
2024     /**
2025      * Returns true if a viewport should always force the height of this
2026      * <code>Scrollable</code> to match the height of the viewport.
2027      * For example a columnar text view that flowed text in left to
2028      * right columns could effectively disable vertical scrolling by
2029      * returning true here.
2030      * <p>
2031      * Scrolling containers, like <code>JViewport</code>,
2032      * will use this method each time they are validated.
2033      *
2034      * @return true if a viewport should force the Scrollables height
2035      *   to match its own
2036      */
2037     @BeanProperty(bound = false)
2038     public boolean getScrollableTracksViewportHeight() {
2039         Container parent = SwingUtilities.getUnwrappedParent(this);
2040         if (parent instanceof JViewport) {
2041             return parent.getHeight() > getPreferredSize().height;
2042         }
2043         return false;
2044     }
2045 
2046 
2047 //////////////////
2048 // Printing Support
2049 //////////////////
2050 
2051     /**
2052      * A convenience print method that displays a print dialog, and then
2053      * prints this {@code JTextComponent} in <i>interactive</i> mode with no
2054      * header or footer text. Note: this method
2055      * blocks until printing is done.
2056      * <p>
2057      * Note: In <i>headless</i> mode, no dialogs will be shown.


2452     }
2453 
2454 
2455 /////////////////
2456 // Accessibility support
2457 ////////////////
2458 
2459 
2460     /**
2461      * Gets the <code>AccessibleContext</code> associated with this
2462      * <code>JTextComponent</code>. For text components,
2463      * the <code>AccessibleContext</code> takes the form of an
2464      * <code>AccessibleJTextComponent</code>.
2465      * A new <code>AccessibleJTextComponent</code> instance
2466      * is created if necessary.
2467      *
2468      * @return an <code>AccessibleJTextComponent</code> that serves as the
2469      *         <code>AccessibleContext</code> of this
2470      *         <code>JTextComponent</code>
2471      */
2472     @BeanProperty(bound = false)
2473     public AccessibleContext getAccessibleContext() {
2474         if (accessibleContext == null) {
2475             accessibleContext = new AccessibleJTextComponent();
2476         }
2477         return accessibleContext;
2478     }
2479 
2480     /**
2481      * This class implements accessibility support for the
2482      * <code>JTextComponent</code> class.  It provides an implementation of
2483      * the Java Accessibility API appropriate to menu user-interface elements.
2484      * <p>
2485      * <strong>Warning:</strong>
2486      * Serialized objects of this class will not be compatible with
2487      * future Swing releases. The current serialization support is
2488      * appropriate for short term storage or RMI between applications running
2489      * the same version of Swing.  As of 1.4, support for long term storage
2490      * of all JavaBeans&trade;
2491      * has been added to the <code>java.beans</code> package.
2492      * Please see {@link java.beans.XMLEncoder}.


4508             } else {
4509                 switch (e.getID()) {
4510                 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4511                     replaceInputMethodText(e);
4512 
4513                     // fall through
4514 
4515                 case InputMethodEvent.CARET_POSITION_CHANGED:
4516                     setInputMethodCaretPosition(e);
4517                     break;
4518                 }
4519             }
4520 
4521             e.consume();
4522         }
4523     }
4524 
4525     //
4526     // Overrides this method to become an active input method client.
4527     //
4528     @BeanProperty(bound = false)
4529     public InputMethodRequests getInputMethodRequests() {
4530         if (inputMethodRequestsHandler == null) {
4531             inputMethodRequestsHandler = new InputMethodRequestsHandler();
4532             Document doc = getDocument();
4533             if (doc != null) {
4534                 doc.addDocumentListener((DocumentListener)inputMethodRequestsHandler);
4535             }
4536         }
4537 
4538         return inputMethodRequestsHandler;
4539     }
4540 
4541     //
4542     // Overrides this method to watch the listener installed.
4543     //
4544     public void addInputMethodListener(InputMethodListener l) {
4545         super.addInputMethodListener(l);
4546         if (l != null) {
4547             needToSendKeyTypedEvent = false;
4548             checkedInputOverride = true;