< prev index next >

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

Print this page




  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.misc.ManagedLocalsThread;
  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>
  92  * The caret is a pluggable object in swing text components.
  93  * Notification of changes to the caret position and the selection
  94  * are sent to implementations of the <code>CaretListener</code>
  95  * interface that have been registered with the text component.
  96  * The UI will install a default caret unless a customized caret
  97  * has been set. <br>
  98  * By default the caret tracks all the document changes
  99  * performed on the Event Dispatching Thread and updates it's position
 100  * accordingly if an insertion occurs before or at the caret position
 101  * or a removal occurs before the caret position. <code>DefaultCaret</code>
 102  * tries to make itself visible which may lead to scrolling
 103  * of a text component within <code>JScrollPane</code>. The default caret
 104  * behavior can be changed by the {@link DefaultCaret#setUpdatePolicy} method.
 105  * <br>
 106  * <b>Note</b>: Non-editable text components also have a caret though
 107  * it may not be painted.
 108  *
 109  * <dt><b>Commands</b>
 110  * <dd>
 111  * Text components provide a number of commands that can be used
 112  * to manipulate the component.  This is essentially the way that
 113  * the component expresses its capabilities.  These are expressed
 114  * in terms of the swing <code>Action</code> interface,
 115  * using the <code>TextAction</code> implementation.
 116  * The set of commands supported by the text component can be
 117  * found with the {@link #getActions} method.  These actions
 118  * can be bound to key events, fired from buttons, etc.
 119  *
 120  * <dt><b>Text Input</b>
 121  * <dd>
 122  * The text components support flexible and internationalized text input, using
 123  * keymaps and the input method framework, while maintaining compatibility with
 124  * the AWT listener model.
 125  * <p>
 126  * A {@link javax.swing.text.Keymap} lets an application bind key
 127  * strokes to actions.
 128  * In order to allow keymaps to be shared across multiple text components, they
 129  * can use actions that extend <code>TextAction</code>.
 130  * <code>TextAction</code> can determine which <code>JTextComponent</code>
 131  * most recently has or had focus and therefore is the subject of
 132  * the action (In the case that the <code>ActionEvent</code>
 133  * sent to the action doesn't contain the target text component as its source).
 134  * <p>
 135  * The <a href="../../../../technotes/guides/imf/spec.html">input method framework</a>
 136  * lets text components interact with input methods, separate software
 137  * components that preprocess events to let users enter thousands of
 138  * different characters using keyboards with far fewer keys.
 139  * <code>JTextComponent</code> is an <em>active client</em> of
 140  * the framework, so it implements the preferred user interface for interacting
 141  * with input methods. As a consequence, some key events do not reach the text
 142  * component because they are handled by an input method, and some text input
 143  * reaches the text component as committed text within an {@link
 144  * java.awt.event.InputMethodEvent} instead of as a key event.
 145  * The complete text input is the combination of the characters in
 146  * <code>keyTyped</code> key events and committed text in input method events.
 147  * <p>
 148  * The AWT listener model lets applications attach event listeners to
 149  * components in order to bind events to actions. Swing encourages the
 150  * use of keymaps instead of listeners, but maintains compatibility
 151  * with listeners by giving the listeners a chance to steal an event
 152  * by consuming it.
 153  * <p>
 154  * Keyboard event and input method events are handled in the following stages,
 155  * with each stage capable of consuming the event:
 156  *
 157  * <table border=1 summary="Stages of keyboard and input method event handling">
 158  * <tr>
 159  * <th id="stage"><p style="text-align:left">Stage</p></th>
 160  * <th id="ke"><p style="text-align:left">KeyEvent</p></th>
 161  * <th id="ime"><p style="text-align:left">InputMethodEvent</p></th></tr>
 162  * <tr><td headers="stage">1.   </td>
 163  *     <td headers="ke">input methods </td>
 164  *     <td headers="ime">(generated here)</td></tr>
 165  * <tr><td headers="stage">2.   </td>
 166  *     <td headers="ke">focus manager </td>


 220  * expression given by SGML, a system used to express a wide variety of
 221  * content.
 222  * Each modification to the document causes notification of the
 223  * details of the change to be sent to all observers in the form of a
 224  * {@link DocumentEvent} which allows the views to stay up to date with the model.
 225  * This event is sent to observers that have implemented the
 226  * {@link DocumentListener}
 227  * interface and registered interest with the model being observed.
 228  *
 229  * <dt><b>Location Information</b>
 230  * <dd>
 231  * The capability of determining the location of text in
 232  * the view is provided.  There are two methods, {@link #modelToView}
 233  * and {@link #viewToModel} for determining this information.
 234  *
 235  * <dt><b>Undo/Redo support</b>
 236  * <dd>
 237  * Support for an edit history mechanism is provided to allow
 238  * undo/redo operations.  The text component does not itself
 239  * provide the history buffer by default, but does provide
 240  * the <code>UndoableEdit</code> records that can be used in conjunction
 241  * with a history buffer to provide the undo/redo support.
 242  * The support is provided by the Document model, which allows
 243  * one to attach UndoableEditListener implementations.
 244  *
 245  * <dt><b>Thread Safety</b>
 246  * <dd>
 247  * The swing text components provide some support of thread
 248  * safe operations.  Because of the high level of configurability
 249  * of the text components, it is possible to circumvent the
 250  * protection provided.  The protection primarily comes from
 251  * the model, so the documentation of <code>AbstractDocument</code>
 252  * describes the assumptions of the protection provided.
 253  * The methods that are safe to call asynchronously are marked
 254  * with comments.
 255  *
 256  * <dt><b>Newlines</b>
 257  * <dd>
 258  * For a discussion on how newlines are handled, see
 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  * @beaninfo
 280  *     attribute: isContainer false
 281  *
 282  * @author  Timothy Prinzing
 283  * @author Igor Kushnirskiy (printing support)
 284  * @see Document
 285  * @see DocumentEvent
 286  * @see DocumentListener
 287  * @see Caret
 288  * @see CaretEvent
 289  * @see CaretListener
 290  * @see TextUI
 291  * @see View
 292  * @see ViewFactory
 293  */
 294 @SuppressWarnings("serial") // Same-version serialization only
 295 public abstract class JTextComponent extends JComponent implements Scrollable, Accessible
 296 {
 297     /**
 298      * Creates a new <code>JTextComponent</code>.
 299      * Listeners for caret events are established, and the pluggable
 300      * UI installed.  The component is marked as editable.  No layout manager
 301      * is used, because layout is managed by the view subsystem of text.
 302      * The document model is set to <code>null</code>.
 303      */
 304     public JTextComponent() {
 305         super();
 306         // enable InputMethodEvent for on-the-spot pre-editing
 307         enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK);
 308         caretEvent = new MutableCaretEvent(this);
 309         addMouseListener(caretEvent);
 310         addFocusListener(caretEvent);
 311         setEditable(true);
 312         setDragEnabled(false);
 313         setLayout(null); // layout is managed by View hierarchy
 314         updateUI();
 315     }
 316 
 317     /**
 318      * Fetches the user-interface factory for this text-oriented editor.
 319      *
 320      * @return the factory
 321      */
 322     public TextUI getUI() { return (TextUI)ui; }
 323 
 324     /**
 325      * Sets the user-interface factory for this text-oriented editor.
 326      *
 327      * @param ui the factory
 328      */
 329     public void setUI(TextUI ui) {
 330         super.setUI(ui);
 331     }
 332 
 333     /**
 334      * Reloads the pluggable UI.  The key used to fetch the
 335      * new interface is <code>getUIClassID()</code>.  The type of
 336      * the UI is <code>TextUI</code>.  <code>invalidate</code>
 337      * is called after setting the UI.
 338      */
 339     public void updateUI() {
 340         setUI((TextUI)UIManager.getUI(this));
 341         invalidate();
 342     }
 343 
 344     /**
 345      * Adds a caret listener for notification of any changes
 346      * to the caret.
 347      *
 348      * @param listener the listener to be added
 349      * @see javax.swing.event.CaretEvent
 350      */
 351     public void addCaretListener(CaretListener listener) {
 352         listenerList.add(CaretListener.class, listener);
 353     }
 354 
 355     /**
 356      * Removes a caret listener.
 357      *
 358      * @param listener the listener to be removed
 359      * @see javax.swing.event.CaretEvent
 360      */
 361     public void removeCaretListener(CaretListener listener) {
 362         listenerList.remove(CaretListener.class, listener);
 363     }
 364 
 365     /**
 366      * Returns an array of all the caret listeners
 367      * registered on this text component.
 368      *
 369      * @return all of this component's <code>CaretListener</code>s
 370      *         or an empty
 371      *         array if no caret listeners are currently registered
 372      *
 373      * @see #addCaretListener
 374      * @see #removeCaretListener
 375      *
 376      * @since 1.4
 377      */
 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


 485             doc.putProperty( TextAttribute.RUN_DIRECTION, runDir );
 486         }
 487         super.setComponentOrientation( o );
 488     }
 489 
 490     /**
 491      * Fetches the command list for the editor.  This is
 492      * the list of commands supported by the plugged-in UI
 493      * augmented by the collection of commands that the
 494      * editor itself supports.  These are useful for binding
 495      * to events, such as in a keymap.
 496      *
 497      * @return the command list
 498      */
 499     public Action[] getActions() {
 500         return getUI().getEditorKit(this).getActions();
 501     }
 502 
 503     /**
 504      * Sets margin space between the text component's border
 505      * and its text.  The text component's default <code>Border</code>
 506      * object will use this value to create the proper margin.
 507      * However, if a non-default border is set on the text component,
 508      * it is that <code>Border</code> object's responsibility to create the
 509      * appropriate margin space (else this property will effectively
 510      * be ignored).  This causes a redraw of the component.
 511      * A PropertyChange event ("margin") is sent to all listeners.
 512      *
 513      * @param m the space between the border and the text
 514      * @beaninfo
 515      *  description: desired space between the border and text area
 516      *        bound: true
 517      */
 518     public void setMargin(Insets m) {
 519         Insets old = margin;
 520         margin = m;
 521         firePropertyChange("margin", old, m);
 522         invalidate();
 523     }
 524 
 525     /**
 526      * Returns the margin between the text component's border and
 527      * its text.
 528      *
 529      * @return the margin
 530      */
 531     public Insets getMargin() {
 532         return margin;
 533     }
 534 
 535     /**
 536      * Sets the <code>NavigationFilter</code>. <code>NavigationFilter</code>
 537      * is used by <code>DefaultCaret</code> and the default cursor movement
 538      * actions as a way to restrict the cursor movement.
 539      * @param filter the filter
 540      *
 541      * @since 1.4
 542      */
 543     public void setNavigationFilter(NavigationFilter filter) {
 544         navigationFilter = filter;
 545     }
 546 
 547     /**
 548      * Returns the <code>NavigationFilter</code>. <code>NavigationFilter</code>
 549      * is used by <code>DefaultCaret</code> and the default cursor movement
 550      * actions as a way to restrict the cursor movement. A null return value
 551      * implies the cursor movement and selection should not be restricted.
 552      *
 553      * @since 1.4
 554      * @return the NavigationFilter
 555      */
 556     public NavigationFilter getNavigationFilter() {
 557         return navigationFilter;
 558     }
 559 
 560     /**
 561      * Fetches the caret that allows text-oriented navigation over
 562      * the view.
 563      *
 564      * @return the caret
 565      */
 566     @Transient
 567     public Caret getCaret() {
 568         return caret;
 569     }


 591         if (caret != null) {
 592             caret.install(this);
 593             caret.addChangeListener(caretEvent);
 594         }
 595         firePropertyChange("caret", old, caret);
 596     }
 597 
 598     /**
 599      * Fetches the object responsible for making highlights.
 600      *
 601      * @return the highlighter
 602      */
 603     public Highlighter getHighlighter() {
 604         return highlighter;
 605     }
 606 
 607     /**
 608      * Sets the highlighter to be used.  By default this will be set
 609      * by the UI that gets installed.  This can be changed to
 610      * a custom highlighter if desired.  The highlighter can be set to
 611      * <code>null</code> to disable it.
 612      * A PropertyChange event ("highlighter") is fired
 613      * when a new highlighter is installed.
 614      *
 615      * @param h the highlighter
 616      * @see #getHighlighter
 617      * @beaninfo
 618      *  description: object responsible for background highlights
 619      *        bound: true
 620      *       expert: true
 621      */
 622     public void setHighlighter(Highlighter h) {
 623         if (highlighter != null) {
 624             highlighter.deinstall(this);
 625         }
 626         Highlighter old = highlighter;
 627         highlighter = h;
 628         if (highlighter != null) {
 629             highlighter.install(this);
 630         }
 631         firePropertyChange("highlighter", old, h);
 632     }
 633 
 634     /**
 635      * Sets the keymap to use for binding events to
 636      * actions.  Setting to <code>null</code> effectively disables
 637      * keyboard input.
 638      * A PropertyChange event ("keymap") is fired when a new keymap
 639      * is installed.
 640      *
 641      * @param map the keymap
 642      * @see #getKeymap
 643      * @beaninfo
 644      *  description: set of key event to action bindings to use
 645      *        bound: true
 646      */
 647     public void setKeymap(Keymap map) {
 648         Keymap old = keymap;
 649         keymap = map;
 650         firePropertyChange("keymap", old, keymap);
 651         updateInputMap(old, map);
 652     }
 653 
 654     /**
 655      * Turns on or off automatic drag handling. In order to enable automatic
 656      * drag handling, this property should be set to {@code true}, and the
 657      * component's {@code TransferHandler} needs to be {@code non-null}.
 658      * The default value of the {@code dragEnabled} property is {@code false}.
 659      * <p>
 660      * The job of honoring this property, and recognizing a user drag gesture,
 661      * lies with the look and feel implementation, and in particular, the component's
 662      * {@code TextUI}. When automatic drag handling is enabled, most look and
 663      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
 664      * drag and drop operation whenever the user presses the mouse button over
 665      * a selection and then moves the mouse a few pixels. Setting this property to
 666      * {@code true} can therefore have a subtle effect on how selections behave.
 667      * <p>
 668      * If a look and feel is used that ignores this property, you can still
 669      * begin a drag and drop operation by calling {@code exportAsDrag} on the
 670      * component's {@code TransferHandler}.
 671      *
 672      * @param b whether or not to enable automatic drag handling
 673      * @exception HeadlessException if
 674      *            <code>b</code> is <code>true</code> and
 675      *            <code>GraphicsEnvironment.isHeadless()</code>
 676      *            returns <code>true</code>
 677      * @see java.awt.GraphicsEnvironment#isHeadless
 678      * @see #getDragEnabled
 679      * @see #setTransferHandler
 680      * @see TransferHandler
 681      * @since 1.4
 682      *
 683      * @beaninfo
 684      *  description: determines whether automatic drag handling is enabled
 685      *        bound: false
 686      */
 687     public void setDragEnabled(boolean b) {
 688         checkDragEnabled(b);
 689         dragEnabled = b;
 690     }
 691 
 692     private static void checkDragEnabled(boolean b) {
 693         if (b && GraphicsEnvironment.isHeadless()) {
 694             throw new HeadlessException();
 695         }
 696     }
 697 
 698     /**
 699      * Returns whether or not automatic drag handling is enabled.
 700      *
 701      * @return the value of the {@code dragEnabled} property
 702      * @see #setDragEnabled
 703      * @since 1.4
 704      */
 705     public boolean getDragEnabled() {
 706         return dragEnabled;
 707     }
 708 
 709     /**
 710      * Sets the drop mode for this component. For backward compatibility,
 711      * the default for this property is <code>DropMode.USE_SELECTION</code>.
 712      * Usage of <code>DropMode.INSERT</code> is recommended, however,
 713      * for an improved user experience. It offers similar behavior of dropping
 714      * between text locations, but does so without affecting the actual text
 715      * selection and caret location.
 716      * <p>
 717      * <code>JTextComponents</code> support the following drop modes:
 718      * <ul>
 719      *    <li><code>DropMode.USE_SELECTION</code></li>
 720      *    <li><code>DropMode.INSERT</code></li>
 721      * </ul>
 722      * <p>
 723      * The drop mode is only meaningful if this component has a
 724      * <code>TransferHandler</code> that accepts drops.
 725      *
 726      * @param dropMode the drop mode to use
 727      * @throws IllegalArgumentException if the drop mode is unsupported
 728      *         or <code>null</code>
 729      * @see #getDropMode
 730      * @see #getDropLocation
 731      * @see #setTransferHandler
 732      * @see javax.swing.TransferHandler
 733      * @since 1.6
 734      */
 735     public final void setDropMode(DropMode dropMode) {
 736         checkDropMode(dropMode);
 737         this.dropMode = dropMode;
 738     }
 739 
 740     private static void checkDropMode(DropMode dropMode) {
 741         if (dropMode != null) {
 742             switch (dropMode) {
 743                 case USE_SELECTION:
 744                 case INSERT:
 745                     return;
 746             }
 747         }
 748 


 766                 public TransferHandler.DropLocation dropLocationForPoint(JTextComponent textComp,
 767                                                                          Point p)
 768                 {
 769                     return textComp.dropLocationForPoint(p);
 770                 }
 771                 public Object setDropLocation(JTextComponent textComp,
 772                                               TransferHandler.DropLocation location,
 773                                               Object state, boolean forDrop)
 774                 {
 775                     return textComp.setDropLocation(location, state, forDrop);
 776                 }
 777             });
 778     }
 779 
 780 
 781     /**
 782      * Calculates a drop location in this component, representing where a
 783      * drop at the given point should insert data.
 784      * <p>
 785      * Note: This method is meant to override
 786      * <code>JComponent.dropLocationForPoint()</code>, which is package-private
 787      * in javax.swing. <code>TransferHandler</code> will detect text components
 788      * and call this method instead via reflection. It's name should therefore
 789      * not be changed.
 790      *
 791      * @param p the point to calculate a drop location for
 792      * @return the drop location, or <code>null</code>
 793      */
 794     DropLocation dropLocationForPoint(Point p) {
 795         Position.Bias[] bias = new Position.Bias[1];
 796         int index = getUI().viewToModel(this, p, bias);
 797 
 798         // viewToModel currently returns null for some HTML content
 799         // when the point is within the component's top inset
 800         if (bias[0] == null) {
 801             bias[0] = Position.Bias.Forward;
 802         }
 803 
 804         return new DropLocation(p, index, bias[0]);
 805     }
 806 
 807     /**
 808      * Called to set or clear the drop location during a DnD operation.
 809      * In some cases, the component may need to use it's internal selection
 810      * temporarily to indicate the drop location. To help facilitate this,
 811      * this method returns and accepts as a parameter a state object.
 812      * This state object can be used to store, and later restore, the selection
 813      * state. Whatever this method returns will be passed back to it in
 814      * future calls, as the state parameter. If it wants the DnD system to
 815      * continue storing the same state, it must pass it back every time.
 816      * Here's how this is used:
 817      * <p>
 818      * Let's say that on the first call to this method the component decides
 819      * to save some state (because it is about to use the selection to show
 820      * a drop index). It can return a state object to the caller encapsulating
 821      * any saved selection state. On a second call, let's say the drop location
 822      * is being changed to something else. The component doesn't need to
 823      * restore anything yet, so it simply passes back the same state object
 824      * to have the DnD system continue storing it. Finally, let's say this
 825      * method is messaged with <code>null</code>. This means DnD
 826      * is finished with this component for now, meaning it should restore
 827      * state. At this point, it can use the state parameter to restore
 828      * said state, and of course return <code>null</code> since there's
 829      * no longer anything to store.
 830      * <p>
 831      * Note: This method is meant to override
 832      * <code>JComponent.setDropLocation()</code>, which is package-private
 833      * in javax.swing. <code>TransferHandler</code> will detect text components
 834      * and call this method instead via reflection. It's name should therefore
 835      * not be changed.
 836      *
 837      * @param location the drop location (as calculated by
 838      *        <code>dropLocationForPoint</code>) or <code>null</code>
 839      *        if there's no longer a valid drop location
 840      * @param state the state object saved earlier for this component,
 841      *        or <code>null</code>
 842      * @param forDrop whether or not the method is being called because an
 843      *        actual drop occurred
 844      * @return any saved state for this component, or <code>null</code> if none
 845      */
 846     Object setDropLocation(TransferHandler.DropLocation location,
 847                            Object state,
 848                            boolean forDrop) {
 849 
 850         Object retVal = null;
 851         DropLocation textLocation = (DropLocation)location;
 852 
 853         if (dropMode == DropMode.USE_SELECTION) {
 854             if (textLocation == null) {
 855                 if (state != null) {
 856                     /*
 857                      * This object represents the state saved earlier.
 858                      *     If the caret is a DefaultCaret it will be
 859                      *     an Object array containing, in order:
 860                      *         - the saved caret mark (Integer)
 861                      *         - the saved caret dot (Integer)
 862                      *         - the saved caret visibility (Boolean)
 863                      *         - the saved mark bias (Position.Bias)
 864                      *         - the saved dot bias (Position.Bias)


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


1042         }
1043     }
1044 
1045     /**
1046      * Fetches the keymap currently active in this text
1047      * component.
1048      *
1049      * @return the keymap
1050      */
1051     public Keymap getKeymap() {
1052         return keymap;
1053     }
1054 
1055     /**
1056      * Adds a new keymap into the keymap hierarchy.  Keymap bindings
1057      * resolve from bottom up so an attribute specified in a child
1058      * will override an attribute specified in the parent.
1059      *
1060      * @param nm   the name of the keymap (must be unique within the
1061      *   collection of named keymaps in the document); the name may
1062      *   be <code>null</code> if the keymap is unnamed,
1063      *   but the caller is responsible for managing the reference
1064      *   returned as an unnamed keymap can't
1065      *   be fetched by name
1066      * @param parent the parent keymap; this may be <code>null</code> if
1067      *   unspecified bindings need not be resolved in some other keymap
1068      * @return the keymap
1069      */
1070     public static Keymap addKeymap(String nm, Keymap parent) {
1071         Keymap map = new DefaultKeymap(nm, parent);
1072         if (nm != null) {
1073             // add a named keymap, a class of bindings
1074             getKeymapTable().put(nm, map);
1075         }
1076         return map;
1077     }
1078 
1079     /**
1080      * Removes a named keymap previously added to the document.  Keymaps
1081      * with <code>null</code> names may not be removed in this way.
1082      *
1083      * @param nm  the name of the keymap to remove
1084      * @return the keymap that was removed
1085      */
1086     public static Keymap removeKeymap(String nm) {
1087         return getKeymapTable().remove(nm);
1088     }
1089 
1090     /**
1091      * Fetches a named keymap previously added to the document.
1092      * This does not work with <code>null</code>-named keymaps.
1093      *
1094      * @param nm  the name of the keymap
1095      * @return the keymap
1096      */
1097     public static Keymap getKeymap(String nm) {
1098         return getKeymapTable().get(nm);
1099     }
1100 
1101     private static HashMap<String,Keymap> getKeymapTable() {
1102         synchronized (KEYMAP_TABLE) {
1103             AppContext appContext = AppContext.getAppContext();
1104             @SuppressWarnings("unchecked")
1105             HashMap<String,Keymap> keymapTable =
1106                 (HashMap<String,Keymap>)appContext.get(KEYMAP_TABLE);
1107             if (keymapTable == null) {
1108                 keymapTable = new HashMap<String,Keymap>(17);
1109                 appContext.put(KEYMAP_TABLE, keymapTable);
1110                 //initialize default keymap
1111                 Keymap binding = addKeymap(DEFAULT_KEYMAP, null);
1112                 binding.setDefaultAction(new
1113                                          DefaultEditorKit.DefaultKeyTypedAction());
1114             }
1115             return keymapTable;
1116         }
1117     }
1118 
1119     /**
1120      * Binding record for creating key bindings.
1121      * <p>
1122      * <strong>Warning:</strong>
1123      * Serialized objects of this class will not be compatible with
1124      * future Swing releases. The current serialization support is
1125      * appropriate for short term storage or RMI between applications running
1126      * the same version of Swing.  As of 1.4, support for long term storage
1127      * of all JavaBeans&trade;
1128      * has been added to the <code>java.beans</code> package.
1129      * Please see {@link java.beans.XMLEncoder}.
1130      */
1131     @SuppressWarnings("serial") // Same-version serialization only
1132     public static class KeyBinding {
1133 
1134         /**
1135          * The key.
1136          */
1137         public KeyStroke key;
1138 
1139         /**
1140          * The name of the action for the key.
1141          */
1142         public String actionName;
1143 
1144         /**
1145          * Creates a new key binding.
1146          *
1147          * @param key the key
1148          * @param actionName the name of the action for the key
1149          */
1150         public KeyBinding(KeyStroke key, String actionName) {
1151             this.key = key;
1152             this.actionName = actionName;
1153         }
1154     }
1155 
1156     /**
1157      * <p>
1158      * Loads a keymap with a bunch of
1159      * bindings.  This can be used to take a static table of
1160      * definitions and load them into some keymap.  The following
1161      * example illustrates an example of binding some keys to
1162      * the cut, copy, and paste actions associated with a
1163      * JTextComponent.  A code fragment to accomplish
1164      * this might look as follows:
1165      * <pre><code>
1166      *
1167      *   static final JTextComponent.KeyBinding[] defaultBindings = {
1168      *     new JTextComponent.KeyBinding(
1169      *       KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK),
1170      *       DefaultEditorKit.copyAction),
1171      *     new JTextComponent.KeyBinding(
1172      *       KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK),
1173      *       DefaultEditorKit.pasteAction),
1174      *     new JTextComponent.KeyBinding(
1175      *       KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK),
1176      *       DefaultEditorKit.cutAction),
1177      *   };
1178      *
1179      *   JTextComponent c = new JTextPane();
1180      *   Keymap k = c.getKeymap();
1181      *   JTextComponent.loadKeymap(k, defaultBindings, c.getActions());
1182      *
1183      * </code></pre>
1184      * The sets of bindings and actions may be empty but must be
1185      * non-<code>null</code>.
1186      *
1187      * @param map the keymap
1188      * @param bindings the bindings
1189      * @param actions the set of actions
1190      */
1191     public static void loadKeymap(Keymap map, KeyBinding[] bindings, Action[] actions) {
1192         Hashtable<String, Action> h = new Hashtable<String, Action>();
1193         for (Action a : actions) {
1194             String value = (String)a.getValue(Action.NAME);
1195             h.put((value!=null ? value:""), a);
1196         }
1197         for (KeyBinding binding : bindings) {
1198             Action a = h.get(binding.actionName);
1199             if (a != null) {
1200                 map.addActionForKeyStroke(binding.key, a);
1201             }
1202         }
1203     }
1204 
1205     /**
1206      * Fetches the current color used to render the
1207      * caret.
1208      *
1209      * @return the color
1210      */
1211     public Color getCaretColor() {
1212         return caretColor;
1213     }
1214 
1215     /**
1216      * Sets the current color used to render the caret.
1217      * Setting to <code>null</code> effectively restores the default color.
1218      * Setting the color results in a PropertyChange event ("caretColor")
1219      * being fired.
1220      *
1221      * @param c the color
1222      * @see #getCaretColor
1223      * @beaninfo
1224      *  description: the color used to render the caret
1225      *        bound: true
1226      *    preferred: true
1227      */
1228     public void setCaretColor(Color c) {
1229         Color old = caretColor;
1230         caretColor = c;
1231         firePropertyChange("caretColor", old, caretColor);
1232     }
1233 
1234     /**
1235      * Fetches the current color used to render the
1236      * selection.
1237      *
1238      * @return the color
1239      */
1240     public Color getSelectionColor() {
1241         return selectionColor;
1242     }
1243 
1244     /**
1245      * Sets the current color used to render the selection.
1246      * Setting the color to <code>null</code> is the same as setting
1247      * <code>Color.white</code>.  Setting the color results in a
1248      * PropertyChange event ("selectionColor").
1249      *
1250      * @param c the color
1251      * @see #getSelectionColor
1252      * @beaninfo
1253      *  description: color used to render selection background
1254      *        bound: true
1255      *    preferred: true
1256      */
1257     public void setSelectionColor(Color c) {
1258         Color old = selectionColor;
1259         selectionColor = c;
1260         firePropertyChange("selectionColor", old, selectionColor);
1261     }
1262 
1263     /**
1264      * Fetches the current color used to render the
1265      * selected text.
1266      *
1267      * @return the color
1268      */
1269     public Color getSelectedTextColor() {
1270         return selectedTextColor;
1271     }
1272 
1273     /**
1274      * Sets the current color used to render the selected text.
1275      * Setting the color to <code>null</code> is the same as
1276      * <code>Color.black</code>. Setting the color results in a
1277      * PropertyChange event ("selectedTextColor") being fired.
1278      *
1279      * @param c the color
1280      * @see #getSelectedTextColor
1281      * @beaninfo
1282      *  description: color used to render selected text
1283      *        bound: true
1284      *    preferred: true
1285      */
1286     public void setSelectedTextColor(Color c) {
1287         Color old = selectedTextColor;
1288         selectedTextColor = c;
1289         firePropertyChange("selectedTextColor", old, selectedTextColor);
1290     }
1291 
1292     /**
1293      * Fetches the current color used to render the
1294      * disabled text.
1295      *
1296      * @return the color


1395      * to the nearest representative location in the model.
1396      * The component must have a positive size for
1397      * this translation to be computed (i.e. layout cannot
1398      * be computed until the component has been sized).  The
1399      * component does not have to be visible or painted.
1400      *
1401      * @param pt the location in the view to translate
1402      * @return the offset &ge; 0 from the start of the document,
1403      *   or -1 if the component does not yet have a positive
1404      *   size.
1405      * @see TextUI#viewToModel
1406      */
1407     public int viewToModel(Point pt) {
1408         return getUI().viewToModel(this, pt);
1409     }
1410 
1411     /**
1412      * Transfers the currently selected range in the associated
1413      * text model to the system clipboard, removing the contents
1414      * from the model.  The current selection is reset.  Does nothing
1415      * for <code>null</code> selections.
1416      *
1417      * @see java.awt.Toolkit#getSystemClipboard
1418      * @see java.awt.datatransfer.Clipboard
1419      */
1420     public void cut() {
1421         if (isEditable() && isEnabled()) {
1422             invokeAction("cut", TransferHandler.getCutAction());
1423         }
1424     }
1425 
1426     /**
1427      * Transfers the currently selected range in the associated
1428      * text model to the system clipboard, leaving the contents
1429      * in the text model.  The current selection remains intact.
1430      * Does nothing for <code>null</code> selections.
1431      *
1432      * @see java.awt.Toolkit#getSystemClipboard
1433      * @see java.awt.datatransfer.Clipboard
1434      */
1435     public void copy() {
1436         invokeAction("copy", TransferHandler.getCopyAction());
1437     }
1438 
1439     /**
1440      * Transfers the contents of the system clipboard into the
1441      * associated text model.  If there is a selection in the
1442      * associated view, it is replaced with the contents of the
1443      * clipboard.  If there is no selection, the clipboard contents
1444      * are inserted in front of the current insert position in
1445      * the associated view.  If the clipboard is empty, does nothing.
1446      *
1447      * @see #replaceSelection
1448      * @see java.awt.Toolkit#getSystemClipboard
1449      * @see java.awt.datatransfer.Clipboard
1450      */
1451     public void paste() {
1452         if (isEditable() && isEnabled()) {
1453             invokeAction("paste", TransferHandler.getPasteAction());
1454         }
1455     }
1456 
1457     /**
1458      * This is a convenience method that is only useful for
1459      * <code>cut</code>, <code>copy</code> and <code>paste</code>.  If
1460      * an <code>Action</code> with the name <code>name</code> does not
1461      * exist in the <code>ActionMap</code>, this will attempt to install a
1462      * <code>TransferHandler</code> and then use <code>altAction</code>.
1463      */
1464     private void invokeAction(String name, Action altAction) {
1465         ActionMap map = getActionMap();
1466         Action action = null;
1467 
1468         if (map != null) {
1469             action = map.get(name);
1470         }
1471         if (action == null) {
1472             installDefaultTransferHandlerIfNecessary();
1473             action = altAction;
1474         }
1475         action.actionPerformed(new ActionEvent(this,
1476                                ActionEvent.ACTION_PERFORMED, (String)action.
1477                                getValue(Action.NAME),
1478                                EventQueue.getMostRecentEventTime(),
1479                                getCurrentEventModifiers()));
1480     }
1481 
1482     /**
1483      * If the current <code>TransferHandler</code> is null, this will
1484      * install a new one.
1485      */
1486     private void installDefaultTransferHandlerIfNecessary() {
1487         if (getTransferHandler() == null) {
1488             if (defaultTransferHandler == null) {
1489                 defaultTransferHandler = new DefaultTransferHandler();
1490             }
1491             setTransferHandler(defaultTransferHandler);
1492         }
1493     }
1494 
1495     /**
1496      * Moves the caret to a new position, leaving behind a mark
1497      * defined by the last time <code>setCaretPosition</code> was
1498      * called.  This forms a selection.
1499      * If the document is <code>null</code>, does nothing. The position
1500      * must be between 0 and the length of the component's text or else
1501      * an exception is thrown.
1502      *
1503      * @param pos the position
1504      * @exception    IllegalArgumentException if the value supplied
1505      *               for <code>position</code> is less than zero or greater
1506      *               than the component's text length
1507      * @see #setCaretPosition
1508      */
1509     public void moveCaretPosition(int pos) {
1510         Document doc = getDocument();
1511         if (doc != null) {
1512             if (pos > doc.getLength() || pos < 0) {
1513                 throw new IllegalArgumentException("bad position: " + pos);
1514             }
1515             caret.moveDot(pos);
1516         }
1517     }
1518 
1519     /**
1520      * The bound property name for the focus accelerator.
1521      */
1522     public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
1523 
1524     /**
1525      * Sets the key accelerator that will cause the receiving text


1555      * text component to get the focus.  Return '\0' if no focus
1556      * accelerator has been set.
1557      *
1558      * @return the key
1559      */
1560     public char getFocusAccelerator() {
1561         return focusAccelerator;
1562     }
1563 
1564     /**
1565      * Initializes from a stream.  This creates a
1566      * model of the type appropriate for the component
1567      * and initializes the model from the stream.
1568      * By default this will load the model as plain
1569      * text.  Previous contents of the model are discarded.
1570      *
1571      * @param in the stream to read from
1572      * @param desc an object describing the stream; this
1573      *   might be a string, a File, a URL, etc.  Some kinds
1574      *   of documents (such as html for example) might be
1575      *   able to make use of this information; if non-<code>null</code>,
1576      *   it is added as a property of the document
1577      * @exception IOException as thrown by the stream being
1578      *  used to initialize
1579      * @see EditorKit#createDefaultDocument
1580      * @see #setDocument
1581      * @see PlainDocument
1582      */
1583     public void read(Reader in, Object desc) throws IOException {
1584         EditorKit kit = getUI().getEditorKit(this);
1585         Document doc = kit.createDefaultDocument();
1586         if (desc != null) {
1587             doc.putProperty(Document.StreamDescriptionProperty, desc);
1588         }
1589         try {
1590             kit.read(in, doc, 0);
1591             setDocument(doc);
1592         } catch (BadLocationException e) {
1593             throw new IOException(e.getMessage());
1594         }
1595     }


1605     public void write(Writer out) throws IOException {
1606         Document doc = getDocument();
1607         try {
1608             getUI().getEditorKit(this).write(out, doc, 0, doc.getLength());
1609         } catch (BadLocationException e) {
1610             throw new IOException(e.getMessage());
1611         }
1612     }
1613 
1614     public void removeNotify() {
1615         super.removeNotify();
1616         if (getFocusedComponent() == this) {
1617             AppContext.getAppContext().remove(FOCUSED_COMPONENT);
1618         }
1619     }
1620 
1621     // --- java.awt.TextComponent methods ------------------------
1622 
1623     /**
1624      * Sets the position of the text insertion caret for the
1625      * <code>TextComponent</code>.  Note that the caret tracks change,
1626      * so this may move if the underlying text of the component is changed.
1627      * If the document is <code>null</code>, does nothing. The position
1628      * must be between 0 and the length of the component's text or else
1629      * an exception is thrown.
1630      *
1631      * @param position the position
1632      * @exception    IllegalArgumentException if the value supplied
1633      *               for <code>position</code> is less than zero or greater
1634      *               than the component's text length
1635      * @beaninfo
1636      * description: the caret position
1637      */
1638     public void setCaretPosition(int position) {
1639         Document doc = getDocument();
1640         if (doc != null) {
1641             if (position > doc.getLength() || position < 0) {
1642                 throw new IllegalArgumentException("bad position: " + position);
1643             }
1644             caret.setDot(position);
1645         }
1646     }
1647 
1648     /**
1649      * Returns the position of the text insertion caret for the
1650      * text component.
1651      *
1652      * @return the position of the text insertion caret for the
1653      *  text component &ge; 0
1654      */
1655     @Transient
1656     public int getCaretPosition() {
1657         return caret.getDot();
1658     }
1659 
1660     /**
1661      * Sets the text of this <code>TextComponent</code>
1662      * to the specified text.  If the text is <code>null</code>
1663      * or empty, has the effect of simply deleting the old text.
1664      * When text has been inserted, the resulting caret location
1665      * is determined by the implementation of the caret class.
1666      *
1667      * <p>
1668      * Note that text is not a bound property, so no <code>PropertyChangeEvent
1669      * </code> is fired when it changes. To listen for changes to the text,
1670      * use <code>DocumentListener</code>.
1671      *
1672      * @param t the new text to be set
1673      * @see #getText
1674      * @see DefaultCaret
1675      * @beaninfo
1676      * description: the text of this component
1677      */
1678     public void setText(String t) {
1679         try {
1680             Document doc = getDocument();
1681             if (doc instanceof AbstractDocument) {
1682                 ((AbstractDocument)doc).replace(0, doc.getLength(), t,null);
1683             }
1684             else {
1685                 doc.remove(0, doc.getLength());
1686                 doc.insertString(0, t, null);
1687             }
1688         } catch (BadLocationException e) {
1689             UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this);
1690         }
1691     }
1692 
1693     /**
1694      * Returns the text contained in this <code>TextComponent</code>.
1695      * If the underlying document is <code>null</code>,
1696      * will give a <code>NullPointerException</code>.
1697      *
1698      * Note that text is not a bound property, so no <code>PropertyChangeEvent
1699      * </code> is fired when it changes. To listen for changes to the text,
1700      * use <code>DocumentListener</code>.
1701      *
1702      * @return the text
1703      * @exception NullPointerException if the document is <code>null</code>
1704      * @see #setText
1705      */
1706     public String getText() {
1707         Document doc = getDocument();
1708         String txt;
1709         try {
1710             txt = doc.getText(0, doc.getLength());
1711         } catch (BadLocationException e) {
1712             txt = null;
1713         }
1714         return txt;
1715     }
1716 
1717     /**
1718      * Returns the selected text contained in this
1719      * <code>TextComponent</code>.  If the selection is
1720      * <code>null</code> or the document empty, returns <code>null</code>.
1721      *
1722      * @return the text
1723      * @exception IllegalArgumentException if the selection doesn't
1724      *  have a valid mapping into the document for some reason
1725      * @see #setText
1726      */
1727     public String getSelectedText() {
1728         String txt = null;
1729         int p0 = Math.min(caret.getDot(), caret.getMark());
1730         int p1 = Math.max(caret.getDot(), caret.getMark());
1731         if (p0 != p1) {
1732             try {
1733                 Document doc = getDocument();
1734                 txt = doc.getText(p0, p1 - p0);
1735             } catch (BadLocationException e) {
1736                 throw new IllegalArgumentException(e.getMessage());
1737             }
1738         }
1739         return txt;
1740     }
1741 
1742     /**
1743      * Returns the boolean indicating whether this
1744      * <code>TextComponent</code> is editable or not.
1745      *
1746      * @return the boolean value
1747      * @see #setEditable
1748      */
1749     public boolean isEditable() {
1750         return editable;
1751     }
1752 
1753     /**
1754      * Sets the specified boolean to indicate whether or not this
1755      * <code>TextComponent</code> should be editable.
1756      * A PropertyChange event ("editable") is fired when the
1757      * state is changed.
1758      *
1759      * @param b the boolean to be set
1760      * @see #isEditable
1761      * @beaninfo
1762      * description: specifies if the text can be edited
1763      *       bound: true
1764      */
1765     public void setEditable(boolean b) {
1766         if (b != editable) {
1767             boolean oldVal = editable;
1768             editable = b;
1769             enableInputMethods(editable);
1770             firePropertyChange("editable", Boolean.valueOf(oldVal), Boolean.valueOf(editable));
1771             repaint();
1772         }
1773     }
1774 
1775     /**
1776      * Returns the selected text's start position.  Return 0 for an
1777      * empty document, or the value of dot if no selection.
1778      *
1779      * @return the start position &ge; 0
1780      */
1781     @Transient
1782     public int getSelectionStart() {
1783         int start = Math.min(caret.getDot(), caret.getMark());
1784         return start;
1785     }
1786 
1787     /**
1788      * Sets the selection start to the specified position.  The new
1789      * starting point is constrained to be before or at the current
1790      * selection end.
1791      * <p>
1792      * This is available for backward compatibility to code
1793      * that called this method on <code>java.awt.TextComponent</code>.
1794      * This is implemented to forward to the <code>Caret</code>
1795      * implementation which is where the actual selection is maintained.
1796      *
1797      * @param selectionStart the start position of the text &ge; 0
1798      * @beaninfo
1799      * description: starting location of the selection.
1800      */
1801     public void setSelectionStart(int selectionStart) {
1802         /* Route through select method to enforce consistent policy
1803          * between selectionStart and selectionEnd.
1804          */
1805         select(selectionStart, getSelectionEnd());
1806     }
1807 
1808     /**
1809      * Returns the selected text's end position.  Return 0 if the document
1810      * is empty, or the value of dot if there is no selection.
1811      *
1812      * @return the end position &ge; 0
1813      */
1814     @Transient
1815     public int getSelectionEnd() {
1816         int end = Math.max(caret.getDot(), caret.getMark());
1817         return end;
1818     }
1819 
1820     /**
1821      * Sets the selection end to the specified position.  The new
1822      * end point is constrained to be at or after the current
1823      * selection start.
1824      * <p>
1825      * This is available for backward compatibility to code
1826      * that called this method on <code>java.awt.TextComponent</code>.
1827      * This is implemented to forward to the <code>Caret</code>
1828      * implementation which is where the actual selection is maintained.
1829      *
1830      * @param selectionEnd the end position of the text &ge; 0
1831      * @beaninfo
1832      * description: ending location of the selection.
1833      */
1834     public void setSelectionEnd(int selectionEnd) {
1835         /* Route through select method to enforce consistent policy
1836          * between selectionStart and selectionEnd.
1837          */
1838         select(getSelectionStart(), selectionEnd);
1839     }
1840 
1841     /**
1842      * Selects the text between the specified start and end positions.
1843      * <p>
1844      * This method sets the start and end positions of the
1845      * selected text, enforcing the restriction that the start position
1846      * must be greater than or equal to zero.  The end position must be
1847      * greater than or equal to the start position, and less than or
1848      * equal to the length of the text component's text.
1849      * <p>
1850      * If the caller supplies values that are inconsistent or out of
1851      * bounds, the method enforces these constraints silently, and
1852      * without failure. Specifically, if the start position or end
1853      * position is greater than the length of the text, it is reset to
1854      * equal the text length. If the start position is less than zero,
1855      * it is reset to zero, and if the end position is less than the
1856      * start position, it is reset to the start position.
1857      * <p>
1858      * This call is provided for backward compatibility.
1859      * It is routed to a call to <code>setCaretPosition</code>
1860      * followed by a call to <code>moveCaretPosition</code>.
1861      * The preferred way to manage selection is by calling
1862      * those methods directly.
1863      *
1864      * @param selectionStart the start position of the text
1865      * @param selectionEnd the end position of the text
1866      * @see #setCaretPosition
1867      * @see #moveCaretPosition
1868      */
1869     public void select(int selectionStart, int selectionEnd) {
1870         // argument adjustment done by java.awt.TextComponent
1871         int docLength = getDocument().getLength();
1872 
1873         if (selectionStart < 0) {
1874             selectionStart = 0;
1875         }
1876         if (selectionStart > docLength) {
1877             selectionStart = docLength;
1878         }
1879         if (selectionEnd > docLength) {
1880             selectionEnd = docLength;
1881         }
1882         if (selectionEnd < selectionStart) {
1883             selectionEnd = selectionStart;
1884         }
1885 
1886         setCaretPosition(selectionStart);
1887         moveCaretPosition(selectionEnd);
1888     }
1889 
1890     /**
1891      * Selects all the text in the <code>TextComponent</code>.
1892      * Does nothing on a <code>null</code> or empty document.
1893      */
1894     public void selectAll() {
1895         Document doc = getDocument();
1896         if (doc != null) {
1897             setCaretPosition(0);
1898             moveCaretPosition(doc.getLength());
1899         }
1900     }
1901 
1902     // --- Tooltip Methods ---------------------------------------------
1903 
1904     /**
1905      * Returns the string to be used as the tooltip for <code>event</code>.
1906      * This will return one of:
1907      * <ol>
1908      *  <li>If <code>setToolTipText</code> has been invoked with a
1909      *      non-<code>null</code>
1910      *      value, it will be returned, otherwise
1911      *  <li>The value from invoking <code>getToolTipText</code> on
1912      *      the UI will be returned.
1913      * </ol>
1914      * By default <code>JTextComponent</code> does not register
1915      * itself with the <code>ToolTipManager</code>.
1916      * This means that tooltips will NOT be shown from the
1917      * <code>TextUI</code> unless <code>registerComponent</code> has
1918      * been invoked on the <code>ToolTipManager</code>.
1919      *
1920      * @param event the event in question
1921      * @return the string to be used as the tooltip for <code>event</code>
1922      * @see javax.swing.JComponent#setToolTipText
1923      * @see javax.swing.plaf.TextUI#getToolTipText
1924      * @see javax.swing.ToolTipManager#registerComponent
1925      */
1926     public String getToolTipText(MouseEvent event) {
1927         String retValue = super.getToolTipText(event);
1928 
1929         if (retValue == null) {
1930             TextUI ui = getUI();
1931             if (ui != null) {
1932                 retValue = ui.getToolTipText(this, new Point(event.getX(),
1933                                                              event.getY()));
1934             }
1935         }
1936         return retValue;
1937     }
1938 
1939     // --- Scrollable methods ---------------------------------------------
1940 
1941     /**
1942      * Returns the preferred size of the viewport for a view component.
1943      * This is implemented to do the default behavior of returning
1944      * the preferred size of the component.
1945      *
1946      * @return the <code>preferredSize</code> of a <code>JViewport</code>
1947      * whose view is this <code>Scrollable</code>
1948      */
1949     public Dimension getPreferredScrollableViewportSize() {
1950         return getPreferredSize();
1951     }
1952 
1953 
1954     /**
1955      * Components that display logical rows or columns should compute
1956      * the scroll increment that will completely expose one new row
1957      * or column, depending on the value of orientation.  Ideally,
1958      * components should handle a partially exposed row or column by
1959      * returning the distance required to completely expose the item.
1960      * <p>
1961      * The default implementation of this is to simply return 10% of
1962      * the visible area.  Subclasses are likely to be able to provide
1963      * a much more reasonable value.
1964      *
1965      * @param visibleRect the view area visible within the viewport
1966      * @param orientation either <code>SwingConstants.VERTICAL</code> or
1967      *   <code>SwingConstants.HORIZONTAL</code>
1968      * @param direction less than zero to scroll up/left, greater than
1969      *   zero for down/right
1970      * @return the "unit" increment for scrolling in the specified direction
1971      * @exception IllegalArgumentException for an invalid orientation
1972      * @see JScrollBar#setUnitIncrement
1973      */
1974     public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
1975         switch(orientation) {
1976         case SwingConstants.VERTICAL:
1977             return visibleRect.height / 10;
1978         case SwingConstants.HORIZONTAL:
1979             return visibleRect.width / 10;
1980         default:
1981             throw new IllegalArgumentException("Invalid orientation: " + orientation);
1982         }
1983     }
1984 
1985 
1986     /**
1987      * Components that display logical rows or columns should compute
1988      * the scroll increment that will completely expose one block
1989      * of rows or columns, depending on the value of orientation.
1990      * <p>
1991      * The default implementation of this is to simply return the visible
1992      * area.  Subclasses will likely be able to provide a much more
1993      * reasonable value.
1994      *
1995      * @param visibleRect the view area visible within the viewport
1996      * @param orientation either <code>SwingConstants.VERTICAL</code> or
1997      *   <code>SwingConstants.HORIZONTAL</code>
1998      * @param direction less than zero to scroll up/left, greater than zero
1999      *  for down/right
2000      * @return the "block" increment for scrolling in the specified direction
2001      * @exception IllegalArgumentException for an invalid orientation
2002      * @see JScrollBar#setBlockIncrement
2003      */
2004     public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
2005         switch(orientation) {
2006         case SwingConstants.VERTICAL:
2007             return visibleRect.height;
2008         case SwingConstants.HORIZONTAL:
2009             return visibleRect.width;
2010         default:
2011             throw new IllegalArgumentException("Invalid orientation: " + orientation);
2012         }
2013     }
2014 
2015 
2016     /**
2017      * Returns true if a viewport should always force the width of this
2018      * <code>Scrollable</code> to match the width of the viewport.
2019      * For example a normal text view that supported line wrapping
2020      * would return true here, since it would be undesirable for
2021      * wrapped lines to disappear beyond the right
2022      * edge of the viewport.  Note that returning true for a
2023      * <code>Scrollable</code> whose ancestor is a <code>JScrollPane</code>
2024      * effectively disables horizontal scrolling.
2025      * <p>
2026      * Scrolling containers, like <code>JViewport</code>,
2027      * will use this method each time they are validated.
2028      *
2029      * @return true if a viewport should force the <code>Scrollable</code>s
2030      *   width to match its own
2031      */
2032     public boolean getScrollableTracksViewportWidth() {
2033         Container parent = SwingUtilities.getUnwrappedParent(this);
2034         if (parent instanceof JViewport) {
2035             return parent.getWidth() > getPreferredSize().width;
2036         }
2037         return false;
2038     }
2039 
2040     /**
2041      * Returns true if a viewport should always force the height of this
2042      * <code>Scrollable</code> to match the height of the viewport.
2043      * For example a columnar text view that flowed text in left to
2044      * right columns could effectively disable vertical scrolling by
2045      * returning true here.
2046      * <p>
2047      * Scrolling containers, like <code>JViewport</code>,
2048      * will use this method each time they are validated.
2049      *
2050      * @return true if a viewport should force the Scrollables height
2051      *   to match its own
2052      */
2053     public boolean getScrollableTracksViewportHeight() {
2054         Container parent = SwingUtilities.getUnwrappedParent(this);
2055         if (parent instanceof JViewport) {
2056             return parent.getHeight() > getPreferredSize().height;
2057         }
2058         return false;
2059     }
2060 
2061 
2062 //////////////////
2063 // Printing Support
2064 //////////////////
2065 
2066     /**
2067      * A convenience print method that displays a print dialog, and then


2456      *
2457      * @see java.awt.print.Printable
2458      * @see java.awt.print.PageFormat
2459      * @see javax.swing.text.Document#render(java.lang.Runnable)
2460      *
2461      * @since 1.6
2462      */
2463     public Printable getPrintable(final MessageFormat headerFormat,
2464                                   final MessageFormat footerFormat) {
2465         return TextComponentPrintable.getPrintable(
2466                    this, headerFormat, footerFormat);
2467     }
2468 
2469 
2470 /////////////////
2471 // Accessibility support
2472 ////////////////
2473 
2474 
2475     /**
2476      * Gets the <code>AccessibleContext</code> associated with this
2477      * <code>JTextComponent</code>. For text components,
2478      * the <code>AccessibleContext</code> takes the form of an
2479      * <code>AccessibleJTextComponent</code>.
2480      * A new <code>AccessibleJTextComponent</code> instance
2481      * is created if necessary.
2482      *
2483      * @return an <code>AccessibleJTextComponent</code> that serves as the
2484      *         <code>AccessibleContext</code> of this
2485      *         <code>JTextComponent</code>
2486      */
2487     public AccessibleContext getAccessibleContext() {
2488         if (accessibleContext == null) {
2489             accessibleContext = new AccessibleJTextComponent();
2490         }
2491         return accessibleContext;
2492     }
2493 
2494     /**
2495      * This class implements accessibility support for the
2496      * <code>JTextComponent</code> class.  It provides an implementation of
2497      * the Java Accessibility API appropriate to menu user-interface elements.
2498      * <p>
2499      * <strong>Warning:</strong>
2500      * Serialized objects of this class will not be compatible with
2501      * future Swing releases. The current serialization support is
2502      * appropriate for short term storage or RMI between applications running
2503      * the same version of Swing.  As of 1.4, support for long term storage
2504      * of all JavaBeans&trade;
2505      * has been added to the <code>java.beans</code> package.
2506      * Please see {@link java.beans.XMLEncoder}.
2507      */
2508     @SuppressWarnings("serial") // Same-version serialization only
2509     public class AccessibleJTextComponent extends AccessibleJComponent
2510     implements AccessibleText, CaretListener, DocumentListener,
2511                AccessibleAction, AccessibleEditableText,
2512                AccessibleExtendedText {
2513 
2514         int caretPos;
2515         Point oldLocationOnScreen;
2516 
2517         /**
2518          * Constructs an AccessibleJTextComponent.  Adds a listener to track
2519          * caret change.
2520          */
2521         public AccessibleJTextComponent() {
2522             Document doc = JTextComponent.this.getDocument();
2523             if (doc != null) {
2524                 doc.addDocumentListener(this);
2525             }


2871          * Return 0 if the text is empty, or the caret position
2872          * if no selection.
2873          *
2874          * @return the index into the text of the end of the selection &ge; 0
2875          */
2876         public int getSelectionEnd() {
2877             return JTextComponent.this.getSelectionEnd();
2878         }
2879 
2880         /**
2881          * Returns the portion of the text that is selected.
2882          *
2883          * @return the text, null if no selection
2884          */
2885         public String getSelectedText() {
2886             return JTextComponent.this.getSelectedText();
2887         }
2888 
2889        /**
2890          * IndexedSegment extends Segment adding the offset into the
2891          * the model the <code>Segment</code> was asked for.
2892          */
2893         private class IndexedSegment extends Segment {
2894             /**
2895              * Offset into the model that the position represents.
2896              */
2897             public int modelOffset;
2898         }
2899 
2900 
2901         // TIGER - 4170173
2902         /**
2903          * Returns the String at a given index. Whitespace
2904          * between words is treated as a word.
2905          *
2906          * @param part the CHARACTER, WORD, or SENTENCE to retrieve
2907          * @param index an index within the text
2908          * @return the letter, word, or sentence.
2909          *
2910          */
2911         public String getAtIndex(int part, int index) {


2923          */
2924         public String getAfterIndex(int part, int index) {
2925             return getAtIndex(part, index, 1);
2926         }
2927 
2928 
2929         /**
2930          * Returns the String before a given index. Whitespace
2931          * between words is treated a word.
2932          *
2933          * @param part the CHARACTER, WORD, or SENTENCE to retrieve
2934          * @param index an index within the text
2935          * @return the letter, word, or sentence.
2936          */
2937         public String getBeforeIndex(int part, int index) {
2938             return getAtIndex(part, index, -1);
2939         }
2940 
2941 
2942         /**
2943          * Gets the word, sentence, or character at <code>index</code>.
2944          * If <code>direction</code> is non-null this will find the
2945          * next/previous word/sentence/character.
2946          */
2947         private String getAtIndex(int part, int index, int direction) {
2948             if (model instanceof AbstractDocument) {
2949                 ((AbstractDocument)model).readLock();
2950             }
2951             try {
2952                 if (index < 0 || index >= model.getLength()) {
2953                     return null;
2954                 }
2955                 switch (part) {
2956                 case AccessibleText.CHARACTER:
2957                     if (index + direction < model.getLength() &&
2958                         index + direction >= 0) {
2959                         return model.getText(index + direction, 1);
2960                     }
2961                     break;
2962 
2963 
2964                 case AccessibleText.WORD:


3010             if (model instanceof PlainDocument ) {
3011                 PlainDocument sdoc = (PlainDocument)model;
3012                 return sdoc.getParagraphElement(index);
3013             } else if (model instanceof StyledDocument) {
3014                 StyledDocument sdoc = (StyledDocument)model;
3015                 return sdoc.getParagraphElement(index);
3016             } else {
3017                 Element para;
3018                 for (para = model.getDefaultRootElement(); ! para.isLeaf(); ) {
3019                     int pos = para.getElementIndex(index);
3020                     para = para.getElement(pos);
3021                 }
3022                 if (para == null) {
3023                     return null;
3024                 }
3025                 return para.getParentElement();
3026             }
3027         }
3028 
3029         /*
3030          * Returns a <code>Segment</code> containing the paragraph text
3031          * at <code>index</code>, or null if <code>index</code> isn't
3032          * valid.
3033          */
3034         private IndexedSegment getParagraphElementText(int index)
3035                                   throws BadLocationException {
3036             Element para = getParagraphElement(index);
3037 
3038 
3039             if (para != null) {
3040                 IndexedSegment segment = new IndexedSegment();
3041                 try {
3042                     int length = para.getEndOffset() - para.getStartOffset();
3043                     model.getText(para.getStartOffset(), length, segment);
3044                 } catch (BadLocationException e) {
3045                     return null;
3046                 }
3047                 segment.modelOffset = para.getStartOffset();
3048                 return segment;
3049             }
3050             return null;
3051         }
3052 
3053 
3054         /**
3055          * Returns the Segment at <code>index</code> representing either
3056          * the paragraph or sentence as identified by <code>part</code>, or
3057          * null if a valid paragraph/sentence can't be found. The offset
3058          * will point to the start of the word/sentence in the array, and
3059          * the modelOffset will point to the location of the word/sentence
3060          * in the model.
3061          */
3062         private IndexedSegment getSegmentAt(int part, int index) throws
3063                                   BadLocationException {
3064             IndexedSegment seg = getParagraphElementText(index);
3065             if (seg == null) {
3066                 return null;
3067             }
3068             BreakIterator iterator;
3069             switch (part) {
3070             case AccessibleText.WORD:
3071                 iterator = BreakIterator.getWordInstance(getLocale());
3072                 break;
3073             case AccessibleText.SENTENCE:
3074                 iterator = BreakIterator.getSentenceInstance(getLocale());
3075                 break;
3076             default:


3255             Document doc = JTextComponent.this.getDocument();
3256             if (doc != null && doc instanceof StyledDocument) {
3257                 StyledDocument sDoc = (StyledDocument)doc;
3258                 int offset = startIndex;
3259                 int length = endIndex - startIndex;
3260                 sDoc.setCharacterAttributes(offset, length, as, true);
3261             }
3262         }
3263 
3264         // ----- end AccessibleEditableText methods
3265 
3266 
3267         // ----- begin AccessibleExtendedText methods
3268 
3269 // Probably should replace the helper method getAtIndex() to return
3270 // instead an AccessibleTextSequence also for LINE & ATTRIBUTE_RUN
3271 // and then make the AccessibleText methods get[At|After|Before]Point
3272 // call this new method instead and return only the string portion
3273 
3274         /**
3275          * Returns the AccessibleTextSequence at a given <code>index</code>.
3276          * If <code>direction</code> is non-null this will find the
3277          * next/previous word/sentence/character.
3278          *
3279          * @param part the <code>CHARACTER</code>, <code>WORD</code>,
3280          * <code>SENTENCE</code>, <code>LINE</code> or
3281          * <code>ATTRIBUTE_RUN</code> to retrieve
3282          * @param index an index within the text
3283          * @param direction is either -1, 0, or 1
3284          * @return an <code>AccessibleTextSequence</code> specifying the text
3285          * if <code>part</code> and <code>index</code> are valid.  Otherwise,
3286          * <code>null</code> is returned.
3287          *
3288          * @see javax.accessibility.AccessibleText#CHARACTER
3289          * @see javax.accessibility.AccessibleText#WORD
3290          * @see javax.accessibility.AccessibleText#SENTENCE
3291          * @see javax.accessibility.AccessibleExtendedText#LINE
3292          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3293          *
3294          * @since 1.6
3295          */
3296         private AccessibleTextSequence getSequenceAtIndex(int part,
3297             int index, int direction) {
3298             if (index < 0 || index >= model.getLength()) {
3299                 return null;
3300             }
3301             if (direction < -1 || direction > 1) {
3302                 return null;    // direction must be 1, 0, or -1
3303             }
3304 
3305             switch (part) {
3306             case AccessibleText.CHARACTER:


3486                     // we are intentionally silent; our contract says we return
3487                     // null if there is any failure in this method
3488                     return null;
3489                 } finally {
3490                     if (model instanceof AbstractDocument) {
3491                         ((AbstractDocument)model).readUnlock();
3492                     }
3493                 }
3494                 return new AccessibleTextSequence(attributeRunStartIndex,
3495                                                   attributeRunEndIndex,
3496                                                   runText);
3497 
3498             default:
3499                 break;
3500             }
3501             return null;
3502         }
3503 
3504 
3505         /**
3506          * Starting at text position <code>index</code>, and going in
3507          * <code>direction</code>, return the edge of run that shares the
3508          * same <code>AttributeSet</code> and parent element as those at
3509          * <code>index</code>.
3510          *
3511          * Note: we assume the document is already locked...
3512          */
3513         private int getRunEdge(int index, int direction) throws
3514          BadLocationException {
3515             if (index < 0 || index >= model.getLength()) {
3516                 throw new BadLocationException("Location out of bounds", index);
3517             }
3518             // locate the Element at index
3519             Element indexElement;
3520             // locate the Element at our index/offset
3521             int elementIndex = -1;        // test for initialization
3522             for (indexElement = model.getDefaultRootElement();
3523                  ! indexElement.isLeaf(); ) {
3524                 elementIndex = indexElement.getElementIndex(index);
3525                 indexElement = indexElement.getElement(elementIndex);
3526             }
3527             if (elementIndex == -1) {
3528                 throw new AssertionError(index);
3529             }


3549                 edgeElement = parent.getElement(edgeElementIndex);
3550                 break;
3551             default:
3552                 throw new AssertionError(direction);
3553             }
3554             switch (direction) {
3555             case -1:
3556                 return edgeElement.getStartOffset();
3557             case 1:
3558                 return edgeElement.getEndOffset();
3559             default:
3560                 // we already caught this case earlier; this is to satisfy
3561                 // the compiler...
3562                 return Integer.MIN_VALUE;
3563             }
3564         }
3565 
3566         // getTextRange() not needed; defined in AccessibleEditableText
3567 
3568         /**
3569          * Returns the <code>AccessibleTextSequence</code> at a given
3570          * <code>index</code>.
3571          *
3572          * @param part the <code>CHARACTER</code>, <code>WORD</code>,
3573          * <code>SENTENCE</code>, <code>LINE</code> or
3574          * <code>ATTRIBUTE_RUN</code> to retrieve
3575          * @param index an index within the text
3576          * @return an <code>AccessibleTextSequence</code> specifying the text if
3577          * <code>part</code> and <code>index</code> are valid.  Otherwise,
3578          * <code>null</code> is returned
3579          *
3580          * @see javax.accessibility.AccessibleText#CHARACTER
3581          * @see javax.accessibility.AccessibleText#WORD
3582          * @see javax.accessibility.AccessibleText#SENTENCE
3583          * @see javax.accessibility.AccessibleExtendedText#LINE
3584          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3585          *
3586          * @since 1.6
3587          */
3588         public AccessibleTextSequence getTextSequenceAt(int part, int index) {
3589             return getSequenceAtIndex(part, index, 0);
3590         }
3591 
3592         /**
3593          * Returns the <code>AccessibleTextSequence</code> after a given
3594          * <code>index</code>.
3595          *
3596          * @param part the <code>CHARACTER</code>, <code>WORD</code>,
3597          * <code>SENTENCE</code>, <code>LINE</code> or
3598          * <code>ATTRIBUTE_RUN</code> to retrieve
3599          * @param index an index within the text
3600          * @return an <code>AccessibleTextSequence</code> specifying the text
3601          * if <code>part</code> and <code>index</code> are valid.  Otherwise,
3602          * <code>null</code> is returned
3603          *
3604          * @see javax.accessibility.AccessibleText#CHARACTER
3605          * @see javax.accessibility.AccessibleText#WORD
3606          * @see javax.accessibility.AccessibleText#SENTENCE
3607          * @see javax.accessibility.AccessibleExtendedText#LINE
3608          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3609          *
3610          * @since 1.6
3611          */
3612         public AccessibleTextSequence getTextSequenceAfter(int part, int index) {
3613             return getSequenceAtIndex(part, index, 1);
3614         }
3615 
3616         /**
3617          * Returns the <code>AccessibleTextSequence</code> before a given
3618          * <code>index</code>.
3619          *
3620          * @param part the <code>CHARACTER</code>, <code>WORD</code>,
3621          * <code>SENTENCE</code>, <code>LINE</code> or
3622          * <code>ATTRIBUTE_RUN</code> to retrieve
3623          * @param index an index within the text
3624          * @return an <code>AccessibleTextSequence</code> specifying the text
3625          * if <code>part</code> and <code>index</code> are valid.  Otherwise,
3626          * <code>null</code> is returned
3627          *
3628          * @see javax.accessibility.AccessibleText#CHARACTER
3629          * @see javax.accessibility.AccessibleText#WORD
3630          * @see javax.accessibility.AccessibleText#SENTENCE
3631          * @see javax.accessibility.AccessibleExtendedText#LINE
3632          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3633          *
3634          * @since 1.6
3635          */
3636         public AccessibleTextSequence getTextSequenceBefore(int part, int index) {
3637             return getSequenceAtIndex(part, index, -1);
3638         }
3639 
3640         /**
3641          * Returns the <code>Rectangle</code> enclosing the text between
3642          * two indicies.
3643          *
3644          * @param startIndex the start index in the text
3645          * @param endIndex the end index in the text
3646          * @return the bounding rectangle of the text if the indices are valid.
3647          * Otherwise, <code>null</code> is returned
3648          *
3649          * @since 1.6
3650          */
3651         public Rectangle getTextBounds(int startIndex, int endIndex) {
3652             if (startIndex < 0 || startIndex > model.getLength()-1 ||
3653                 endIndex < 0 || endIndex > model.getLength()-1 ||
3654                 startIndex > endIndex) {
3655                 return null;
3656             }
3657             TextUI ui = getUI();
3658             if (ui == null) {
3659                 return null;
3660             }
3661             Rectangle rect = null;
3662             Rectangle alloc = getRootEditorRect();
3663             if (alloc == null) {
3664                 return null;
3665             }
3666             if (model instanceof AbstractDocument) {
3667                 ((AbstractDocument)model).readLock();


3834     private Color caretColor;
3835     private Color selectionColor;
3836     private Color selectedTextColor;
3837     private Color disabledTextColor;
3838     private boolean editable;
3839     private Insets margin;
3840     private char focusAccelerator;
3841     private boolean dragEnabled;
3842 
3843     /**
3844      * The drop mode for this component.
3845      */
3846     private DropMode dropMode = DropMode.USE_SELECTION;
3847 
3848     /**
3849      * The drop location.
3850      */
3851     private transient DropLocation dropLocation;
3852 
3853     /**
3854      * Represents a drop location for <code>JTextComponent</code>s.
3855      *
3856      * @see #getDropLocation
3857      * @since 1.6
3858      */
3859     public static final class DropLocation extends TransferHandler.DropLocation {
3860         private final int index;
3861         private final Position.Bias bias;
3862 
3863         private DropLocation(Point p, int index, Position.Bias bias) {
3864             super(p);
3865             this.index = index;
3866             this.bias = bias;
3867         }
3868 
3869         /**
3870          * Returns the index where dropped data should be inserted into the
3871          * associated component. This index represents a position between
3872          * characters, as would be interpreted by a caret.
3873          *
3874          * @return the drop index


3892          * and the content and format of the returned string may vary
3893          * between implementations.
3894          *
3895          * @return a string representation of this drop location
3896          */
3897         public String toString() {
3898             return getClass().getName()
3899                    + "[dropPoint=" + getDropPoint() + ","
3900                    + "index=" + index + ","
3901                    + "bias=" + bias + "]";
3902         }
3903     }
3904 
3905     /**
3906      * TransferHandler used if one hasn't been supplied by the UI.
3907      */
3908     private static DefaultTransferHandler defaultTransferHandler;
3909 
3910     /**
3911      * Maps from class name to Boolean indicating if
3912      * <code>processInputMethodEvent</code> has been overriden.
3913      */
3914     private static Cache<Class<?>,Boolean> METHOD_OVERRIDDEN
3915             = new Cache<Class<?>,Boolean>(Cache.Kind.WEAK, Cache.Kind.STRONG) {
3916         /**
3917          * Returns {@code true} if the specified {@code type} extends {@link JTextComponent}
3918          * and the {@link JTextComponent#processInputMethodEvent} method is overridden.
3919          */
3920         @Override
3921         public Boolean create(final Class<?> type) {
3922             if (JTextComponent.class == type) {
3923                 return Boolean.FALSE;
3924             }
3925             if (get(type.getSuperclass())) {
3926                 return Boolean.TRUE;
3927             }
3928             return AccessController.doPrivileged(
3929                     new PrivilegedAction<Boolean>() {
3930                         public Boolean run() {
3931                             try {
3932                                 type.getDeclaredMethod("processInputMethodEvent", InputMethodEvent.class);
3933                                 return Boolean.TRUE;
3934                             } catch (NoSuchMethodException exception) {
3935                                 return Boolean.FALSE;
3936                             }
3937                         }
3938                     });
3939         }
3940     };
3941 
3942     /**
3943      * Returns a string representation of this <code>JTextComponent</code>.
3944      * This method is intended to be used only for debugging purposes, and the
3945      * content and format of the returned string may vary between
3946      * implementations. The returned string may be empty but may not
3947      * be <code>null</code>.
3948      * <P>
3949      * Overriding <code>paramString</code> to provide information about the
3950      * specific new aspects of the JFC components.
3951      *
3952      * @return  a string representation of this <code>JTextComponent</code>
3953      */
3954     protected String paramString() {
3955         String editableString = (editable ?
3956                                  "true" : "false");
3957         String caretColorString = (caretColor != null ?
3958                                    caretColor.toString() : "");
3959         String selectionColorString = (selectionColor != null ?
3960                                        selectionColor.toString() : "");
3961         String selectedTextColorString = (selectedTextColor != null ?
3962                                           selectedTextColor.toString() : "");
3963         String disabledTextColorString = (disabledTextColor != null ?
3964                                           disabledTextColor.toString() : "");
3965         String marginString = (margin != null ?
3966                                margin.toString() : "");
3967 
3968         return super.paramString() +
3969         ",caretColor=" + caretColorString +
3970         ",disabledTextColor=" + disabledTextColorString +
3971         ",editable=" + editableString +
3972         ",margin=" + marginString +


4245          * String representation of the keymap... potentially
4246          * a very long string.
4247          */
4248         public String toString() {
4249             return "Keymap[" + nm + "]" + bindings;
4250         }
4251 
4252         String nm;
4253         Keymap parent;
4254         Hashtable<KeyStroke, Action> bindings;
4255         Action defaultAction;
4256     }
4257 
4258 
4259     /**
4260      * KeymapWrapper wraps a Keymap inside an InputMap. For KeymapWrapper
4261      * to be useful it must be used with a KeymapActionMap.
4262      * KeymapWrapper for the most part, is an InputMap with two parents.
4263      * The first parent visited is ALWAYS the Keymap, with the second
4264      * parent being the parent inherited from InputMap. If
4265      * <code>keymap.getAction</code> returns null, implying the Keymap
4266      * does not have a binding for the KeyStroke,
4267      * the parent is then visited. If the Keymap has a binding, the
4268      * Action is returned, if not and the KeyStroke represents a
4269      * KeyTyped event and the Keymap has a defaultAction,
4270      * <code>DefaultActionKey</code> is returned.
4271      * <p>KeymapActionMap is then able to transate the object passed in
4272      * to either message the Keymap, or message its default implementation.
4273      */
4274     static class KeymapWrapper extends InputMap {
4275         static final Object DefaultActionKey = new Object();
4276 
4277         private Keymap keymap;
4278 
4279         KeymapWrapper(Keymap keymap) {
4280             this.keymap = keymap;
4281         }
4282 
4283         public KeyStroke[] keys() {
4284             KeyStroke[] sKeys = super.keys();
4285             KeyStroke[] keymapKeys = keymap.getBoundKeyStrokes();
4286             int sCount = (sKeys == null) ? 0 : sKeys.length;
4287             int keymapCount = (keymapKeys == null) ? 0 : keymapKeys.length;
4288             if (sCount == 0) {
4289                 return keymapKeys;
4290             }


4308 
4309         public Object get(KeyStroke keyStroke) {
4310             Object retValue = keymap.getAction(keyStroke);
4311             if (retValue == null) {
4312                 retValue = super.get(keyStroke);
4313                 if (retValue == null &&
4314                     keyStroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED &&
4315                     keymap.getDefaultAction() != null) {
4316                     // Implies this is a KeyTyped event, use the default
4317                     // action.
4318                     retValue = DefaultActionKey;
4319                 }
4320             }
4321             return retValue;
4322         }
4323     }
4324 
4325 
4326     /**
4327      * Wraps a Keymap inside an ActionMap. This is used with
4328      * a KeymapWrapper. If <code>get</code> is passed in
4329      * <code>KeymapWrapper.DefaultActionKey</code>, the default action is
4330      * returned, otherwise if the key is an Action, it is returned.
4331      */
4332     static class KeymapActionMap extends ActionMap {
4333         private Keymap keymap;
4334 
4335         KeymapActionMap(Keymap keymap) {
4336             this.keymap = keymap;
4337         }
4338 
4339         public Object[] keys() {
4340             Object[] sKeys = super.keys();
4341             Object[] keymapKeys = keymap.getBoundActions();
4342             int sCount = (sKeys == null) ? 0 : sKeys.length;
4343             int keymapCount = (keymapKeys == null) ? 0 : keymapKeys.length;
4344             boolean hasDefault = (keymap.getDefaultAction() != null);
4345             if (hasDefault) {
4346                 keymapCount++;
4347             }
4348             if (sCount == 0) {
4349                 if (hasDefault) {


4393                 // Try the Keymap.
4394                 if (key == KeymapWrapper.DefaultActionKey) {
4395                     retValue = keymap.getDefaultAction();
4396                 }
4397                 else if (key instanceof Action) {
4398                     // This is a little iffy, technically an Action is
4399                     // a valid Key. We're assuming the Action came from
4400                     // the InputMap though.
4401                     retValue = (Action)key;
4402                 }
4403             }
4404             return retValue;
4405         }
4406     }
4407 
4408     private static final Object FOCUSED_COMPONENT =
4409         new StringBuilder("JTextComponent_FocusedComponent");
4410 
4411     /**
4412      * The default keymap that will be shared by all
4413      * <code>JTextComponent</code> instances unless they
4414      * have had a different keymap set.
4415      */
4416     public static final String DEFAULT_KEYMAP = "default";
4417 
4418     /**
4419      * Event to use when firing a notification of change to caret
4420      * position.  This is mutable so that the event can be reused
4421      * since caret events can be fairly high in bandwidth.
4422      */
4423     static class MutableCaretEvent extends CaretEvent implements ChangeListener, FocusListener, MouseListener {
4424 
4425         MutableCaretEvent(JTextComponent c) {
4426             super(c);
4427         }
4428 
4429         final void fire() {
4430             JTextComponent c = (JTextComponent) getSource();
4431             if (c != null) {
4432                 Caret caret = c.getCaret();
4433                 dot = caret.getDot();




  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.misc.ManagedLocalsThread;
  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} is the base class for swing text
  79  * components.  It tries to be compatible with the
  80  * {@code java.awt.TextComponent} 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>
  92  * The caret is a pluggable object in swing text components.
  93  * Notification of changes to the caret position and the selection
  94  * are sent to implementations of the {@code CaretListener}
  95  * interface that have been registered with the text component.
  96  * The UI will install a default caret unless a customized caret
  97  * has been set. <br>
  98  * By default the caret tracks all the document changes
  99  * performed on the Event Dispatching Thread and updates it's position
 100  * accordingly if an insertion occurs before or at the caret position
 101  * or a removal occurs before the caret position. {@code DefaultCaret}
 102  * tries to make itself visible which may lead to scrolling
 103  * of a text component within {@code JScrollPane}. The default caret
 104  * behavior can be changed by the {@link DefaultCaret#setUpdatePolicy} method.
 105  * <br>
 106  * <b>Note</b>: Non-editable text components also have a caret though
 107  * it may not be painted.
 108  *
 109  * <dt><b>Commands</b>
 110  * <dd>
 111  * Text components provide a number of commands that can be used
 112  * to manipulate the component.  This is essentially the way that
 113  * the component expresses its capabilities.  These are expressed
 114  * in terms of the swing {@code Action} interface,
 115  * using the {@code TextAction} implementation.
 116  * The set of commands supported by the text component can be
 117  * found with the {@link #getActions} method.  These actions
 118  * can be bound to key events, fired from buttons, etc.
 119  *
 120  * <dt><b>Text Input</b>
 121  * <dd>
 122  * The text components support flexible and internationalized text input, using
 123  * keymaps and the input method framework, while maintaining compatibility with
 124  * the AWT listener model.
 125  * <p>
 126  * A {@link javax.swing.text.Keymap} lets an application bind key
 127  * strokes to actions.
 128  * In order to allow keymaps to be shared across multiple text components, they
 129  * can use actions that extend {@code TextAction}.
 130  * {@code TextAction} can determine which {@code JTextComponent}
 131  * most recently has or had focus and therefore is the subject of
 132  * the action (In the case that the {@code ActionEvent}
 133  * sent to the action doesn't contain the target text component as its source).
 134  * <p>
 135  * The <a href="../../../../technotes/guides/imf/spec.html">input method framework</a>
 136  * lets text components interact with input methods, separate software
 137  * components that preprocess events to let users enter thousands of
 138  * different characters using keyboards with far fewer keys.
 139  * {@code JTextComponent} is an <em>active client</em> of
 140  * the framework, so it implements the preferred user interface for interacting
 141  * with input methods. As a consequence, some key events do not reach the text
 142  * component because they are handled by an input method, and some text input
 143  * reaches the text component as committed text within an {@link
 144  * java.awt.event.InputMethodEvent} instead of as a key event.
 145  * The complete text input is the combination of the characters in
 146  * {@code keyTyped} key events and committed text in input method events.
 147  * <p>
 148  * The AWT listener model lets applications attach event listeners to
 149  * components in order to bind events to actions. Swing encourages the
 150  * use of keymaps instead of listeners, but maintains compatibility
 151  * with listeners by giving the listeners a chance to steal an event
 152  * by consuming it.
 153  * <p>
 154  * Keyboard event and input method events are handled in the following stages,
 155  * with each stage capable of consuming the event:
 156  *
 157  * <table border=1 summary="Stages of keyboard and input method event handling">
 158  * <tr>
 159  * <th id="stage"><p style="text-align:left">Stage</p></th>
 160  * <th id="ke"><p style="text-align:left">KeyEvent</p></th>
 161  * <th id="ime"><p style="text-align:left">InputMethodEvent</p></th></tr>
 162  * <tr><td headers="stage">1.   </td>
 163  *     <td headers="ke">input methods </td>
 164  *     <td headers="ime">(generated here)</td></tr>
 165  * <tr><td headers="stage">2.   </td>
 166  *     <td headers="ke">focus manager </td>


 220  * expression given by SGML, a system used to express a wide variety of
 221  * content.
 222  * Each modification to the document causes notification of the
 223  * details of the change to be sent to all observers in the form of a
 224  * {@link DocumentEvent} which allows the views to stay up to date with the model.
 225  * This event is sent to observers that have implemented the
 226  * {@link DocumentListener}
 227  * interface and registered interest with the model being observed.
 228  *
 229  * <dt><b>Location Information</b>
 230  * <dd>
 231  * The capability of determining the location of text in
 232  * the view is provided.  There are two methods, {@link #modelToView}
 233  * and {@link #viewToModel} for determining this information.
 234  *
 235  * <dt><b>Undo/Redo support</b>
 236  * <dd>
 237  * Support for an edit history mechanism is provided to allow
 238  * undo/redo operations.  The text component does not itself
 239  * provide the history buffer by default, but does provide
 240  * the {@code UndoableEdit} records that can be used in conjunction
 241  * with a history buffer to provide the undo/redo support.
 242  * The support is provided by the Document model, which allows
 243  * one to attach UndoableEditListener implementations.
 244  *
 245  * <dt><b>Thread Safety</b>
 246  * <dd>
 247  * The swing text components provide some support of thread
 248  * safe operations.  Because of the high level of configurability
 249  * of the text components, it is possible to circumvent the
 250  * protection provided.  The protection primarily comes from
 251  * the model, so the documentation of {@code AbstractDocument}
 252  * describes the assumptions of the protection provided.
 253  * The methods that are safe to call asynchronously are marked
 254  * with comments.
 255  *
 256  * <dt><b>Newlines</b>
 257  * <dd>
 258  * For a discussion on how newlines are handled, see
 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} package.
 277  * Please see {@link java.beans.XMLEncoder}.
 278  *
 279  * @beaninfo
 280  *     attribute: isContainer false
 281  *
 282  * @author  Timothy Prinzing
 283  * @author Igor Kushnirskiy (printing support)
 284  * @see Document
 285  * @see DocumentEvent
 286  * @see DocumentListener
 287  * @see Caret
 288  * @see CaretEvent
 289  * @see CaretListener
 290  * @see TextUI
 291  * @see View
 292  * @see ViewFactory
 293  */
 294 @SuppressWarnings("serial") // Same-version serialization only
 295 public abstract class JTextComponent extends JComponent implements Scrollable, Accessible
 296 {
 297     /**
 298      * Creates a new {@code JTextComponent}.
 299      * Listeners for caret events are established, and the pluggable
 300      * UI installed.  The component is marked as editable.  No layout manager
 301      * is used, because layout is managed by the view subsystem of text.
 302      * The document model is set to {@code null}.
 303      */
 304     public JTextComponent() {
 305         super();
 306         // enable InputMethodEvent for on-the-spot pre-editing
 307         enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK);
 308         caretEvent = new MutableCaretEvent(this);
 309         addMouseListener(caretEvent);
 310         addFocusListener(caretEvent);
 311         setEditable(true);
 312         setDragEnabled(false);
 313         setLayout(null); // layout is managed by View hierarchy
 314         updateUI();
 315     }
 316 
 317     /**
 318      * Fetches the user-interface factory for this text-oriented editor.
 319      *
 320      * @return the factory
 321      */
 322     public TextUI getUI() { return (TextUI)ui; }
 323 
 324     /**
 325      * Sets the user-interface factory for this text-oriented editor.
 326      *
 327      * @param ui the factory
 328      */
 329     public void setUI(TextUI ui) {
 330         super.setUI(ui);
 331     }
 332 
 333     /**
 334      * Reloads the pluggable UI.  The key used to fetch the
 335      * new interface is {@code getUIClassID()}.  The type of
 336      * the UI is {@code TextUI}.  {@code invalidate}
 337      * is called after setting the UI.
 338      */
 339     public void updateUI() {
 340         setUI((TextUI)UIManager.getUI(this));
 341         invalidate();
 342     }
 343 
 344     /**
 345      * Adds a caret listener for notification of any changes
 346      * to the caret.
 347      *
 348      * @param listener the listener to be added
 349      * @see javax.swing.event.CaretEvent
 350      */
 351     public void addCaretListener(CaretListener listener) {
 352         listenerList.add(CaretListener.class, listener);
 353     }
 354 
 355     /**
 356      * Removes a caret listener.
 357      *
 358      * @param listener the listener to be removed
 359      * @see javax.swing.event.CaretEvent
 360      */
 361     public void removeCaretListener(CaretListener listener) {
 362         listenerList.remove(CaretListener.class, listener);
 363     }
 364 
 365     /**
 366      * Returns an array of all the caret listeners
 367      * registered on this text component.
 368      *
 369      * @return all of this component's {@code CaretListener}s
 370      *         or an empty
 371      *         array if no caret listeners are currently registered
 372      *
 373      * @see #addCaretListener
 374      * @see #removeCaretListener
 375      *
 376      * @since 1.4
 377      */
 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


 485             doc.putProperty( TextAttribute.RUN_DIRECTION, runDir );
 486         }
 487         super.setComponentOrientation( o );
 488     }
 489 
 490     /**
 491      * Fetches the command list for the editor.  This is
 492      * the list of commands supported by the plugged-in UI
 493      * augmented by the collection of commands that the
 494      * editor itself supports.  These are useful for binding
 495      * to events, such as in a keymap.
 496      *
 497      * @return the command list
 498      */
 499     public Action[] getActions() {
 500         return getUI().getEditorKit(this).getActions();
 501     }
 502 
 503     /**
 504      * Sets margin space between the text component's border
 505      * and its text.  The text component's default {@code Border}
 506      * object will use this value to create the proper margin.
 507      * However, if a non-default border is set on the text component,
 508      * it is that {@code Border} object's responsibility to create the
 509      * appropriate margin space (else this property will effectively
 510      * be ignored).  This causes a redraw of the component.
 511      * A PropertyChange event ("margin") is sent to all listeners.
 512      *
 513      * @param m the space between the border and the text
 514      * @beaninfo
 515      *  description: desired space between the border and text area
 516      *        bound: true
 517      */
 518     public void setMargin(Insets m) {
 519         Insets old = margin;
 520         margin = m;
 521         firePropertyChange("margin", old, m);
 522         invalidate();
 523     }
 524 
 525     /**
 526      * Returns the margin between the text component's border and
 527      * its text.
 528      *
 529      * @return the margin
 530      */
 531     public Insets getMargin() {
 532         return margin;
 533     }
 534 
 535     /**
 536      * Sets the {@code NavigationFilter}. {@code NavigationFilter}
 537      * is used by {@code DefaultCaret} and the default cursor movement
 538      * actions as a way to restrict the cursor movement.
 539      * @param filter the filter
 540      *
 541      * @since 1.4
 542      */
 543     public void setNavigationFilter(NavigationFilter filter) {
 544         navigationFilter = filter;
 545     }
 546 
 547     /**
 548      * Returns the {@code NavigationFilter}. {@code NavigationFilter}
 549      * is used by {@code DefaultCaret} and the default cursor movement
 550      * actions as a way to restrict the cursor movement. A null return value
 551      * implies the cursor movement and selection should not be restricted.
 552      *
 553      * @since 1.4
 554      * @return the NavigationFilter
 555      */
 556     public NavigationFilter getNavigationFilter() {
 557         return navigationFilter;
 558     }
 559 
 560     /**
 561      * Fetches the caret that allows text-oriented navigation over
 562      * the view.
 563      *
 564      * @return the caret
 565      */
 566     @Transient
 567     public Caret getCaret() {
 568         return caret;
 569     }


 591         if (caret != null) {
 592             caret.install(this);
 593             caret.addChangeListener(caretEvent);
 594         }
 595         firePropertyChange("caret", old, caret);
 596     }
 597 
 598     /**
 599      * Fetches the object responsible for making highlights.
 600      *
 601      * @return the highlighter
 602      */
 603     public Highlighter getHighlighter() {
 604         return highlighter;
 605     }
 606 
 607     /**
 608      * Sets the highlighter to be used.  By default this will be set
 609      * by the UI that gets installed.  This can be changed to
 610      * a custom highlighter if desired.  The highlighter can be set to
 611      * {@code null} to disable it.
 612      * A PropertyChange event ("highlighter") is fired
 613      * when a new highlighter is installed.
 614      *
 615      * @param h the highlighter
 616      * @see #getHighlighter
 617      * @beaninfo
 618      *  description: object responsible for background highlights
 619      *        bound: true
 620      *       expert: true
 621      */
 622     public void setHighlighter(Highlighter h) {
 623         if (highlighter != null) {
 624             highlighter.deinstall(this);
 625         }
 626         Highlighter old = highlighter;
 627         highlighter = h;
 628         if (highlighter != null) {
 629             highlighter.install(this);
 630         }
 631         firePropertyChange("highlighter", old, h);
 632     }
 633 
 634     /**
 635      * Sets the keymap to use for binding events to
 636      * actions.  Setting to {@code null} effectively disables
 637      * keyboard input.
 638      * A PropertyChange event ("keymap") is fired when a new keymap
 639      * is installed.
 640      *
 641      * @param map the keymap
 642      * @see #getKeymap
 643      * @beaninfo
 644      *  description: set of key event to action bindings to use
 645      *        bound: true
 646      */
 647     public void setKeymap(Keymap map) {
 648         Keymap old = keymap;
 649         keymap = map;
 650         firePropertyChange("keymap", old, keymap);
 651         updateInputMap(old, map);
 652     }
 653 
 654     /**
 655      * Turns on or off automatic drag handling. In order to enable automatic
 656      * drag handling, this property should be set to {@code true}, and the
 657      * component's {@code TransferHandler} needs to be {@code non-null}.
 658      * The default value of the {@code dragEnabled} property is {@code false}.
 659      * <p>
 660      * The job of honoring this property, and recognizing a user drag gesture,
 661      * lies with the look and feel implementation, and in particular, the component's
 662      * {@code TextUI}. When automatic drag handling is enabled, most look and
 663      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
 664      * drag and drop operation whenever the user presses the mouse button over
 665      * a selection and then moves the mouse a few pixels. Setting this property to
 666      * {@code true} can therefore have a subtle effect on how selections behave.
 667      * <p>
 668      * If a look and feel is used that ignores this property, you can still
 669      * begin a drag and drop operation by calling {@code exportAsDrag} on the
 670      * component's {@code TransferHandler}.
 671      *
 672      * @param b whether or not to enable automatic drag handling
 673      * @exception HeadlessException if
 674      *            {@code b} is {@code true} and
 675      *            {@code GraphicsEnvironment.isHeadless()}
 676      *            returns {@code true}
 677      * @see java.awt.GraphicsEnvironment#isHeadless
 678      * @see #getDragEnabled
 679      * @see #setTransferHandler
 680      * @see TransferHandler
 681      * @since 1.4
 682      *
 683      * @beaninfo
 684      *  description: determines whether automatic drag handling is enabled
 685      *        bound: false
 686      */
 687     public void setDragEnabled(boolean b) {
 688         checkDragEnabled(b);
 689         dragEnabled = b;
 690     }
 691 
 692     private static void checkDragEnabled(boolean b) {
 693         if (b && GraphicsEnvironment.isHeadless()) {
 694             throw new HeadlessException();
 695         }
 696     }
 697 
 698     /**
 699      * Returns whether or not automatic drag handling is enabled.
 700      *
 701      * @return the value of the {@code dragEnabled} property
 702      * @see #setDragEnabled
 703      * @since 1.4
 704      */
 705     public boolean getDragEnabled() {
 706         return dragEnabled;
 707     }
 708 
 709     /**
 710      * Sets the drop mode for this component. For backward compatibility,
 711      * the default for this property is {@code DropMode.USE_SELECTION}.
 712      * Usage of {@code DropMode.INSERT} is recommended, however,
 713      * for an improved user experience. It offers similar behavior of dropping
 714      * between text locations, but does so without affecting the actual text
 715      * selection and caret location.
 716      * <p>
 717      * {@code JTextComponents} support the following drop modes:
 718      * <ul>
 719      *    <li>{@code DropMode.USE_SELECTION}</li>
 720      *    <li>{@code DropMode.INSERT}</li>
 721      * </ul>
 722      * <p>
 723      * The drop mode is only meaningful if this component has a
 724      * {@code TransferHandler} that accepts drops.
 725      *
 726      * @param dropMode the drop mode to use
 727      * @throws IllegalArgumentException if the drop mode is unsupported
 728      *         or {@code null}
 729      * @see #getDropMode
 730      * @see #getDropLocation
 731      * @see #setTransferHandler
 732      * @see javax.swing.TransferHandler
 733      * @since 1.6
 734      */
 735     public final void setDropMode(DropMode dropMode) {
 736         checkDropMode(dropMode);
 737         this.dropMode = dropMode;
 738     }
 739 
 740     private static void checkDropMode(DropMode dropMode) {
 741         if (dropMode != null) {
 742             switch (dropMode) {
 743                 case USE_SELECTION:
 744                 case INSERT:
 745                     return;
 746             }
 747         }
 748 


 766                 public TransferHandler.DropLocation dropLocationForPoint(JTextComponent textComp,
 767                                                                          Point p)
 768                 {
 769                     return textComp.dropLocationForPoint(p);
 770                 }
 771                 public Object setDropLocation(JTextComponent textComp,
 772                                               TransferHandler.DropLocation location,
 773                                               Object state, boolean forDrop)
 774                 {
 775                     return textComp.setDropLocation(location, state, forDrop);
 776                 }
 777             });
 778     }
 779 
 780 
 781     /**
 782      * Calculates a drop location in this component, representing where a
 783      * drop at the given point should insert data.
 784      * <p>
 785      * Note: This method is meant to override
 786      * {@code JComponent.dropLocationForPoint()}, which is package-private
 787      * in javax.swing. {@code TransferHandler} will detect text components
 788      * and call this method instead via reflection. It's name should therefore
 789      * not be changed.
 790      *
 791      * @param p the point to calculate a drop location for
 792      * @return the drop location, or {@code null}
 793      */
 794     DropLocation dropLocationForPoint(Point p) {
 795         Position.Bias[] bias = new Position.Bias[1];
 796         int index = getUI().viewToModel(this, p, bias);
 797 
 798         // viewToModel currently returns null for some HTML content
 799         // when the point is within the component's top inset
 800         if (bias[0] == null) {
 801             bias[0] = Position.Bias.Forward;
 802         }
 803 
 804         return new DropLocation(p, index, bias[0]);
 805     }
 806 
 807     /**
 808      * Called to set or clear the drop location during a DnD operation.
 809      * In some cases, the component may need to use it's internal selection
 810      * temporarily to indicate the drop location. To help facilitate this,
 811      * this method returns and accepts as a parameter a state object.
 812      * This state object can be used to store, and later restore, the selection
 813      * state. Whatever this method returns will be passed back to it in
 814      * future calls, as the state parameter. If it wants the DnD system to
 815      * continue storing the same state, it must pass it back every time.
 816      * Here's how this is used:
 817      * <p>
 818      * Let's say that on the first call to this method the component decides
 819      * to save some state (because it is about to use the selection to show
 820      * a drop index). It can return a state object to the caller encapsulating
 821      * any saved selection state. On a second call, let's say the drop location
 822      * is being changed to something else. The component doesn't need to
 823      * restore anything yet, so it simply passes back the same state object
 824      * to have the DnD system continue storing it. Finally, let's say this
 825      * method is messaged with {@code null}. This means DnD
 826      * is finished with this component for now, meaning it should restore
 827      * state. At this point, it can use the state parameter to restore
 828      * said state, and of course return {@code null} since there's
 829      * no longer anything to store.
 830      * <p>
 831      * Note: This method is meant to override
 832      * {@code JComponent.setDropLocation()}, which is package-private
 833      * in javax.swing. {@code TransferHandler} will detect text components
 834      * and call this method instead via reflection. It's name should therefore
 835      * not be changed.
 836      *
 837      * @param location the drop location (as calculated by
 838      *        {@code dropLocationForPoint}) or {@code null}
 839      *        if there's no longer a valid drop location
 840      * @param state the state object saved earlier for this component,
 841      *        or {@code null}
 842      * @param forDrop whether or not the method is being called because an
 843      *        actual drop occurred
 844      * @return any saved state for this component, or {@code null} if none
 845      */
 846     Object setDropLocation(TransferHandler.DropLocation location,
 847                            Object state,
 848                            boolean forDrop) {
 849 
 850         Object retVal = null;
 851         DropLocation textLocation = (DropLocation)location;
 852 
 853         if (dropMode == DropMode.USE_SELECTION) {
 854             if (textLocation == null) {
 855                 if (state != null) {
 856                     /*
 857                      * This object represents the state saved earlier.
 858                      *     If the caret is a DefaultCaret it will be
 859                      *     an Object array containing, in order:
 860                      *         - the saved caret mark (Integer)
 861                      *         - the saved caret dot (Integer)
 862                      *         - the saved caret visibility (Boolean)
 863                      *         - the saved mark bias (Position.Bias)
 864                      *         - the saved dot bias (Position.Bias)


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


1042         }
1043     }
1044 
1045     /**
1046      * Fetches the keymap currently active in this text
1047      * component.
1048      *
1049      * @return the keymap
1050      */
1051     public Keymap getKeymap() {
1052         return keymap;
1053     }
1054 
1055     /**
1056      * Adds a new keymap into the keymap hierarchy.  Keymap bindings
1057      * resolve from bottom up so an attribute specified in a child
1058      * will override an attribute specified in the parent.
1059      *
1060      * @param nm   the name of the keymap (must be unique within the
1061      *   collection of named keymaps in the document); the name may
1062      *   be {@code null} if the keymap is unnamed,
1063      *   but the caller is responsible for managing the reference
1064      *   returned as an unnamed keymap can't
1065      *   be fetched by name
1066      * @param parent the parent keymap; this may be {@code null} if
1067      *   unspecified bindings need not be resolved in some other keymap
1068      * @return the keymap
1069      */
1070     public static Keymap addKeymap(String nm, Keymap parent) {
1071         Keymap map = new DefaultKeymap(nm, parent);
1072         if (nm != null) {
1073             // add a named keymap, a class of bindings
1074             getKeymapTable().put(nm, map);
1075         }
1076         return map;
1077     }
1078 
1079     /**
1080      * Removes a named keymap previously added to the document.  Keymaps
1081      * with {@code null} names may not be removed in this way.
1082      *
1083      * @param nm  the name of the keymap to remove
1084      * @return the keymap that was removed
1085      */
1086     public static Keymap removeKeymap(String nm) {
1087         return getKeymapTable().remove(nm);
1088     }
1089 
1090     /**
1091      * Fetches a named keymap previously added to the document.
1092      * This does not work with {@code null}-named keymaps.
1093      *
1094      * @param nm  the name of the keymap
1095      * @return the keymap
1096      */
1097     public static Keymap getKeymap(String nm) {
1098         return getKeymapTable().get(nm);
1099     }
1100 
1101     private static HashMap<String,Keymap> getKeymapTable() {
1102         synchronized (KEYMAP_TABLE) {
1103             AppContext appContext = AppContext.getAppContext();
1104             @SuppressWarnings("unchecked")
1105             HashMap<String,Keymap> keymapTable =
1106                 (HashMap<String,Keymap>)appContext.get(KEYMAP_TABLE);
1107             if (keymapTable == null) {
1108                 keymapTable = new HashMap<String,Keymap>(17);
1109                 appContext.put(KEYMAP_TABLE, keymapTable);
1110                 //initialize default keymap
1111                 Keymap binding = addKeymap(DEFAULT_KEYMAP, null);
1112                 binding.setDefaultAction(new
1113                                          DefaultEditorKit.DefaultKeyTypedAction());
1114             }
1115             return keymapTable;
1116         }
1117     }
1118 
1119     /**
1120      * Binding record for creating key bindings.
1121      * <p>
1122      * <strong>Warning:</strong>
1123      * Serialized objects of this class will not be compatible with
1124      * future Swing releases. The current serialization support is
1125      * appropriate for short term storage or RMI between applications running
1126      * the same version of Swing.  As of 1.4, support for long term storage
1127      * of all JavaBeans&trade;
1128      * has been added to the {@code java.beans} package.
1129      * Please see {@link java.beans.XMLEncoder}.
1130      */
1131     @SuppressWarnings("serial") // Same-version serialization only
1132     public static class KeyBinding {
1133 
1134         /**
1135          * The key.
1136          */
1137         public KeyStroke key;
1138 
1139         /**
1140          * The name of the action for the key.
1141          */
1142         public String actionName;
1143 
1144         /**
1145          * Creates a new key binding.
1146          *
1147          * @param key the key
1148          * @param actionName the name of the action for the key
1149          */
1150         public KeyBinding(KeyStroke key, String actionName) {
1151             this.key = key;
1152             this.actionName = actionName;
1153         }
1154     }
1155 
1156     /**
1157      * <p>
1158      * Loads a keymap with a bunch of
1159      * bindings.  This can be used to take a static table of
1160      * definitions and load them into some keymap.  The following
1161      * example illustrates an example of binding some keys to
1162      * the cut, copy, and paste actions associated with a
1163      * JTextComponent.  A code fragment to accomplish
1164      * this might look as follows:
1165      * <pre>{@code
1166      *
1167      *   static final JTextComponent.KeyBinding[] defaultBindings = {
1168      *     new JTextComponent.KeyBinding(
1169      *       KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK),
1170      *       DefaultEditorKit.copyAction),
1171      *     new JTextComponent.KeyBinding(
1172      *       KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK),
1173      *       DefaultEditorKit.pasteAction),
1174      *     new JTextComponent.KeyBinding(
1175      *       KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK),
1176      *       DefaultEditorKit.cutAction),
1177      *   };
1178      *
1179      *   JTextComponent c = new JTextPane();
1180      *   Keymap k = c.getKeymap();
1181      *   JTextComponent.loadKeymap(k, defaultBindings, c.getActions());
1182      *
1183      * }</pre>
1184      * The sets of bindings and actions may be empty but must be
1185      * non-{@code null}.
1186      *
1187      * @param map the keymap
1188      * @param bindings the bindings
1189      * @param actions the set of actions
1190      */
1191     public static void loadKeymap(Keymap map, KeyBinding[] bindings, Action[] actions) {
1192         Hashtable<String, Action> h = new Hashtable<String, Action>();
1193         for (Action a : actions) {
1194             String value = (String)a.getValue(Action.NAME);
1195             h.put((value!=null ? value:""), a);
1196         }
1197         for (KeyBinding binding : bindings) {
1198             Action a = h.get(binding.actionName);
1199             if (a != null) {
1200                 map.addActionForKeyStroke(binding.key, a);
1201             }
1202         }
1203     }
1204 
1205     /**
1206      * Fetches the current color used to render the
1207      * caret.
1208      *
1209      * @return the color
1210      */
1211     public Color getCaretColor() {
1212         return caretColor;
1213     }
1214 
1215     /**
1216      * Sets the current color used to render the caret.
1217      * Setting to {@code null} effectively restores the default color.
1218      * Setting the color results in a PropertyChange event ("caretColor")
1219      * being fired.
1220      *
1221      * @param c the color
1222      * @see #getCaretColor
1223      * @beaninfo
1224      *  description: the color used to render the caret
1225      *        bound: true
1226      *    preferred: true
1227      */
1228     public void setCaretColor(Color c) {
1229         Color old = caretColor;
1230         caretColor = c;
1231         firePropertyChange("caretColor", old, caretColor);
1232     }
1233 
1234     /**
1235      * Fetches the current color used to render the
1236      * selection.
1237      *
1238      * @return the color
1239      */
1240     public Color getSelectionColor() {
1241         return selectionColor;
1242     }
1243 
1244     /**
1245      * Sets the current color used to render the selection.
1246      * Setting the color to {@code null} is the same as setting
1247      * {@code Color.white}.  Setting the color results in a
1248      * PropertyChange event ("selectionColor").
1249      *
1250      * @param c the color
1251      * @see #getSelectionColor
1252      * @beaninfo
1253      *  description: color used to render selection background
1254      *        bound: true
1255      *    preferred: true
1256      */
1257     public void setSelectionColor(Color c) {
1258         Color old = selectionColor;
1259         selectionColor = c;
1260         firePropertyChange("selectionColor", old, selectionColor);
1261     }
1262 
1263     /**
1264      * Fetches the current color used to render the
1265      * selected text.
1266      *
1267      * @return the color
1268      */
1269     public Color getSelectedTextColor() {
1270         return selectedTextColor;
1271     }
1272 
1273     /**
1274      * Sets the current color used to render the selected text.
1275      * Setting the color to {@code null} is the same as
1276      * {@code Color.black}. Setting the color results in a
1277      * PropertyChange event ("selectedTextColor") being fired.
1278      *
1279      * @param c the color
1280      * @see #getSelectedTextColor
1281      * @beaninfo
1282      *  description: color used to render selected text
1283      *        bound: true
1284      *    preferred: true
1285      */
1286     public void setSelectedTextColor(Color c) {
1287         Color old = selectedTextColor;
1288         selectedTextColor = c;
1289         firePropertyChange("selectedTextColor", old, selectedTextColor);
1290     }
1291 
1292     /**
1293      * Fetches the current color used to render the
1294      * disabled text.
1295      *
1296      * @return the color


1395      * to the nearest representative location in the model.
1396      * The component must have a positive size for
1397      * this translation to be computed (i.e. layout cannot
1398      * be computed until the component has been sized).  The
1399      * component does not have to be visible or painted.
1400      *
1401      * @param pt the location in the view to translate
1402      * @return the offset &ge; 0 from the start of the document,
1403      *   or -1 if the component does not yet have a positive
1404      *   size.
1405      * @see TextUI#viewToModel
1406      */
1407     public int viewToModel(Point pt) {
1408         return getUI().viewToModel(this, pt);
1409     }
1410 
1411     /**
1412      * Transfers the currently selected range in the associated
1413      * text model to the system clipboard, removing the contents
1414      * from the model.  The current selection is reset.  Does nothing
1415      * for {@code null} selections.
1416      *
1417      * @see java.awt.Toolkit#getSystemClipboard
1418      * @see java.awt.datatransfer.Clipboard
1419      */
1420     public void cut() {
1421         if (isEditable() && isEnabled()) {
1422             invokeAction("cut", TransferHandler.getCutAction());
1423         }
1424     }
1425 
1426     /**
1427      * Transfers the currently selected range in the associated
1428      * text model to the system clipboard, leaving the contents
1429      * in the text model.  The current selection remains intact.
1430      * Does nothing for {@code null} selections.
1431      *
1432      * @see java.awt.Toolkit#getSystemClipboard
1433      * @see java.awt.datatransfer.Clipboard
1434      */
1435     public void copy() {
1436         invokeAction("copy", TransferHandler.getCopyAction());
1437     }
1438 
1439     /**
1440      * Transfers the contents of the system clipboard into the
1441      * associated text model.  If there is a selection in the
1442      * associated view, it is replaced with the contents of the
1443      * clipboard.  If there is no selection, the clipboard contents
1444      * are inserted in front of the current insert position in
1445      * the associated view.  If the clipboard is empty, does nothing.
1446      *
1447      * @see #replaceSelection
1448      * @see java.awt.Toolkit#getSystemClipboard
1449      * @see java.awt.datatransfer.Clipboard
1450      */
1451     public void paste() {
1452         if (isEditable() && isEnabled()) {
1453             invokeAction("paste", TransferHandler.getPasteAction());
1454         }
1455     }
1456 
1457     /**
1458      * This is a convenience method that is only useful for
1459      * {@code cut}, {@code copy} and {@code paste}.  If
1460      * an {@code Action} with the name {@code name} does not
1461      * exist in the {@code ActionMap}, this will attempt to install a
1462      * {@code TransferHandler} and then use {@code altAction}.
1463      */
1464     private void invokeAction(String name, Action altAction) {
1465         ActionMap map = getActionMap();
1466         Action action = null;
1467 
1468         if (map != null) {
1469             action = map.get(name);
1470         }
1471         if (action == null) {
1472             installDefaultTransferHandlerIfNecessary();
1473             action = altAction;
1474         }
1475         action.actionPerformed(new ActionEvent(this,
1476                                ActionEvent.ACTION_PERFORMED, (String)action.
1477                                getValue(Action.NAME),
1478                                EventQueue.getMostRecentEventTime(),
1479                                getCurrentEventModifiers()));
1480     }
1481 
1482     /**
1483      * If the current {@code TransferHandler} is null, this will
1484      * install a new one.
1485      */
1486     private void installDefaultTransferHandlerIfNecessary() {
1487         if (getTransferHandler() == null) {
1488             if (defaultTransferHandler == null) {
1489                 defaultTransferHandler = new DefaultTransferHandler();
1490             }
1491             setTransferHandler(defaultTransferHandler);
1492         }
1493     }
1494 
1495     /**
1496      * Moves the caret to a new position, leaving behind a mark
1497      * defined by the last time {@code setCaretPosition} was
1498      * called.  This forms a selection.
1499      * If the document is {@code null}, does nothing. The position
1500      * must be between 0 and the length of the component's text or else
1501      * an exception is thrown.
1502      *
1503      * @param pos the position
1504      * @exception    IllegalArgumentException if the value supplied
1505      *               for {@code position} is less than zero or greater
1506      *               than the component's text length
1507      * @see #setCaretPosition
1508      */
1509     public void moveCaretPosition(int pos) {
1510         Document doc = getDocument();
1511         if (doc != null) {
1512             if (pos > doc.getLength() || pos < 0) {
1513                 throw new IllegalArgumentException("bad position: " + pos);
1514             }
1515             caret.moveDot(pos);
1516         }
1517     }
1518 
1519     /**
1520      * The bound property name for the focus accelerator.
1521      */
1522     public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
1523 
1524     /**
1525      * Sets the key accelerator that will cause the receiving text


1555      * text component to get the focus.  Return '\0' if no focus
1556      * accelerator has been set.
1557      *
1558      * @return the key
1559      */
1560     public char getFocusAccelerator() {
1561         return focusAccelerator;
1562     }
1563 
1564     /**
1565      * Initializes from a stream.  This creates a
1566      * model of the type appropriate for the component
1567      * and initializes the model from the stream.
1568      * By default this will load the model as plain
1569      * text.  Previous contents of the model are discarded.
1570      *
1571      * @param in the stream to read from
1572      * @param desc an object describing the stream; this
1573      *   might be a string, a File, a URL, etc.  Some kinds
1574      *   of documents (such as html for example) might be
1575      *   able to make use of this information; if non-{@code null},
1576      *   it is added as a property of the document
1577      * @exception IOException as thrown by the stream being
1578      *  used to initialize
1579      * @see EditorKit#createDefaultDocument
1580      * @see #setDocument
1581      * @see PlainDocument
1582      */
1583     public void read(Reader in, Object desc) throws IOException {
1584         EditorKit kit = getUI().getEditorKit(this);
1585         Document doc = kit.createDefaultDocument();
1586         if (desc != null) {
1587             doc.putProperty(Document.StreamDescriptionProperty, desc);
1588         }
1589         try {
1590             kit.read(in, doc, 0);
1591             setDocument(doc);
1592         } catch (BadLocationException e) {
1593             throw new IOException(e.getMessage());
1594         }
1595     }


1605     public void write(Writer out) throws IOException {
1606         Document doc = getDocument();
1607         try {
1608             getUI().getEditorKit(this).write(out, doc, 0, doc.getLength());
1609         } catch (BadLocationException e) {
1610             throw new IOException(e.getMessage());
1611         }
1612     }
1613 
1614     public void removeNotify() {
1615         super.removeNotify();
1616         if (getFocusedComponent() == this) {
1617             AppContext.getAppContext().remove(FOCUSED_COMPONENT);
1618         }
1619     }
1620 
1621     // --- java.awt.TextComponent methods ------------------------
1622 
1623     /**
1624      * Sets the position of the text insertion caret for the
1625      * {@code TextComponent}.  Note that the caret tracks change,
1626      * so this may move if the underlying text of the component is changed.
1627      * If the document is {@code null}, does nothing. The position
1628      * must be between 0 and the length of the component's text or else
1629      * an exception is thrown.
1630      *
1631      * @param position the position
1632      * @exception    IllegalArgumentException if the value supplied
1633      *               for {@code position} is less than zero or greater
1634      *               than the component's text length
1635      * @beaninfo
1636      * description: the caret position
1637      */
1638     public void setCaretPosition(int position) {
1639         Document doc = getDocument();
1640         if (doc != null) {
1641             if (position > doc.getLength() || position < 0) {
1642                 throw new IllegalArgumentException("bad position: " + position);
1643             }
1644             caret.setDot(position);
1645         }
1646     }
1647 
1648     /**
1649      * Returns the position of the text insertion caret for the
1650      * text component.
1651      *
1652      * @return the position of the text insertion caret for the
1653      *  text component &ge; 0
1654      */
1655     @Transient
1656     public int getCaretPosition() {
1657         return caret.getDot();
1658     }
1659 
1660     /**
1661      * Sets the text of this {@code TextComponent}
1662      * to the specified text.  If the text is {@code null}
1663      * or empty, has the effect of simply deleting the old text.
1664      * When text has been inserted, the resulting caret location
1665      * is determined by the implementation of the caret class.
1666      *
1667      * <p>
1668      * Note that text is not a bound property, so no {@code PropertyChangeEvent}
1669      * is fired when it changes. To listen for changes to the text,
1670      * use {@code DocumentListener}.
1671      *
1672      * @param t the new text to be set
1673      * @see #getText
1674      * @see DefaultCaret
1675      * @beaninfo
1676      * description: the text of this component
1677      */
1678     public void setText(String t) {
1679         try {
1680             Document doc = getDocument();
1681             if (doc instanceof AbstractDocument) {
1682                 ((AbstractDocument)doc).replace(0, doc.getLength(), t,null);
1683             }
1684             else {
1685                 doc.remove(0, doc.getLength());
1686                 doc.insertString(0, t, null);
1687             }
1688         } catch (BadLocationException e) {
1689             UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this);
1690         }
1691     }
1692 
1693     /**
1694      * Returns the text contained in this {@code TextComponent}.
1695      * If the underlying document is {@code null},
1696      * will give a {@code NullPointerException}.
1697      *
1698      * Note that text is not a bound property, so no {@code PropertyChangeEvent}
1699      * is fired when it changes. To listen for changes to the text,
1700      * use {@code DocumentListener}.
1701      *
1702      * @return the text
1703      * @exception NullPointerException if the document is {@code null}
1704      * @see #setText
1705      */
1706     public String getText() {
1707         Document doc = getDocument();
1708         String txt;
1709         try {
1710             txt = doc.getText(0, doc.getLength());
1711         } catch (BadLocationException e) {
1712             txt = null;
1713         }
1714         return txt;
1715     }
1716 
1717     /**
1718      * Returns the selected text contained in this
1719      * {@code TextComponent}.  If the selection is
1720      * {@code null} or the document empty, returns {@code null}.
1721      *
1722      * @return the text
1723      * @exception IllegalArgumentException if the selection doesn't
1724      *  have a valid mapping into the document for some reason
1725      * @see #setText
1726      */
1727     public String getSelectedText() {
1728         String txt = null;
1729         int p0 = Math.min(caret.getDot(), caret.getMark());
1730         int p1 = Math.max(caret.getDot(), caret.getMark());
1731         if (p0 != p1) {
1732             try {
1733                 Document doc = getDocument();
1734                 txt = doc.getText(p0, p1 - p0);
1735             } catch (BadLocationException e) {
1736                 throw new IllegalArgumentException(e.getMessage());
1737             }
1738         }
1739         return txt;
1740     }
1741 
1742     /**
1743      * Returns the boolean indicating whether this
1744      * {@code TextComponent} is editable or not.
1745      *
1746      * @return the boolean value
1747      * @see #setEditable
1748      */
1749     public boolean isEditable() {
1750         return editable;
1751     }
1752 
1753     /**
1754      * Sets the specified boolean to indicate whether or not this
1755      * {@code TextComponent} should be editable.
1756      * A PropertyChange event ("editable") is fired when the
1757      * state is changed.
1758      *
1759      * @param b the boolean to be set
1760      * @see #isEditable
1761      * @beaninfo
1762      * description: specifies if the text can be edited
1763      *       bound: true
1764      */
1765     public void setEditable(boolean b) {
1766         if (b != editable) {
1767             boolean oldVal = editable;
1768             editable = b;
1769             enableInputMethods(editable);
1770             firePropertyChange("editable", Boolean.valueOf(oldVal), Boolean.valueOf(editable));
1771             repaint();
1772         }
1773     }
1774 
1775     /**
1776      * Returns the selected text's start position.  Return 0 for an
1777      * empty document, or the value of dot if no selection.
1778      *
1779      * @return the start position &ge; 0
1780      */
1781     @Transient
1782     public int getSelectionStart() {
1783         int start = Math.min(caret.getDot(), caret.getMark());
1784         return start;
1785     }
1786 
1787     /**
1788      * Sets the selection start to the specified position.  The new
1789      * starting point is constrained to be before or at the current
1790      * selection end.
1791      * <p>
1792      * This is available for backward compatibility to code
1793      * that called this method on {@code java.awt.TextComponent}.
1794      * This is implemented to forward to the {@code Caret}
1795      * implementation which is where the actual selection is maintained.
1796      *
1797      * @param selectionStart the start position of the text &ge; 0
1798      * @beaninfo
1799      * description: starting location of the selection.
1800      */
1801     public void setSelectionStart(int selectionStart) {
1802         /* Route through select method to enforce consistent policy
1803          * between selectionStart and selectionEnd.
1804          */
1805         select(selectionStart, getSelectionEnd());
1806     }
1807 
1808     /**
1809      * Returns the selected text's end position.  Return 0 if the document
1810      * is empty, or the value of dot if there is no selection.
1811      *
1812      * @return the end position &ge; 0
1813      */
1814     @Transient
1815     public int getSelectionEnd() {
1816         int end = Math.max(caret.getDot(), caret.getMark());
1817         return end;
1818     }
1819 
1820     /**
1821      * Sets the selection end to the specified position.  The new
1822      * end point is constrained to be at or after the current
1823      * selection start.
1824      * <p>
1825      * This is available for backward compatibility to code
1826      * that called this method on {@code java.awt.TextComponent}.
1827      * This is implemented to forward to the {@code Caret}
1828      * implementation which is where the actual selection is maintained.
1829      *
1830      * @param selectionEnd the end position of the text &ge; 0
1831      * @beaninfo
1832      * description: ending location of the selection.
1833      */
1834     public void setSelectionEnd(int selectionEnd) {
1835         /* Route through select method to enforce consistent policy
1836          * between selectionStart and selectionEnd.
1837          */
1838         select(getSelectionStart(), selectionEnd);
1839     }
1840 
1841     /**
1842      * Selects the text between the specified start and end positions.
1843      * <p>
1844      * This method sets the start and end positions of the
1845      * selected text, enforcing the restriction that the start position
1846      * must be greater than or equal to zero.  The end position must be
1847      * greater than or equal to the start position, and less than or
1848      * equal to the length of the text component's text.
1849      * <p>
1850      * If the caller supplies values that are inconsistent or out of
1851      * bounds, the method enforces these constraints silently, and
1852      * without failure. Specifically, if the start position or end
1853      * position is greater than the length of the text, it is reset to
1854      * equal the text length. If the start position is less than zero,
1855      * it is reset to zero, and if the end position is less than the
1856      * start position, it is reset to the start position.
1857      * <p>
1858      * This call is provided for backward compatibility.
1859      * It is routed to a call to {@code setCaretPosition}
1860      * followed by a call to {@code moveCaretPosition}.
1861      * The preferred way to manage selection is by calling
1862      * those methods directly.
1863      *
1864      * @param selectionStart the start position of the text
1865      * @param selectionEnd the end position of the text
1866      * @see #setCaretPosition
1867      * @see #moveCaretPosition
1868      */
1869     public void select(int selectionStart, int selectionEnd) {
1870         // argument adjustment done by java.awt.TextComponent
1871         int docLength = getDocument().getLength();
1872 
1873         if (selectionStart < 0) {
1874             selectionStart = 0;
1875         }
1876         if (selectionStart > docLength) {
1877             selectionStart = docLength;
1878         }
1879         if (selectionEnd > docLength) {
1880             selectionEnd = docLength;
1881         }
1882         if (selectionEnd < selectionStart) {
1883             selectionEnd = selectionStart;
1884         }
1885 
1886         setCaretPosition(selectionStart);
1887         moveCaretPosition(selectionEnd);
1888     }
1889 
1890     /**
1891      * Selects all the text in the {@code TextComponent}.
1892      * Does nothing on a {@code null} or empty document.
1893      */
1894     public void selectAll() {
1895         Document doc = getDocument();
1896         if (doc != null) {
1897             setCaretPosition(0);
1898             moveCaretPosition(doc.getLength());
1899         }
1900     }
1901 
1902     // --- Tooltip Methods ---------------------------------------------
1903 
1904     /**
1905      * Returns the string to be used as the tooltip for {@code event}.
1906      * This will return one of:
1907      * <ol>
1908      *  <li>If {@code setToolTipText} has been invoked with a
1909      *      non-{@code null}
1910      *      value, it will be returned, otherwise
1911      *  <li>The value from invoking {@code getToolTipText} on
1912      *      the UI will be returned.
1913      * </ol>
1914      * By default {@code JTextComponent} does not register
1915      * itself with the {@code ToolTipManager}.
1916      * This means that tooltips will NOT be shown from the
1917      * {@code TextUI} unless {@code registerComponent} has
1918      * been invoked on the {@code ToolTipManager}.
1919      *
1920      * @param event the event in question
1921      * @return the string to be used as the tooltip for {@code event}
1922      * @see javax.swing.JComponent#setToolTipText
1923      * @see javax.swing.plaf.TextUI#getToolTipText
1924      * @see javax.swing.ToolTipManager#registerComponent
1925      */
1926     public String getToolTipText(MouseEvent event) {
1927         String retValue = super.getToolTipText(event);
1928 
1929         if (retValue == null) {
1930             TextUI ui = getUI();
1931             if (ui != null) {
1932                 retValue = ui.getToolTipText(this, new Point(event.getX(),
1933                                                              event.getY()));
1934             }
1935         }
1936         return retValue;
1937     }
1938 
1939     // --- Scrollable methods ---------------------------------------------
1940 
1941     /**
1942      * Returns the preferred size of the viewport for a view component.
1943      * This is implemented to do the default behavior of returning
1944      * the preferred size of the component.
1945      *
1946      * @return the {@code preferredSize} of a {@code JViewport}
1947      * whose view is this {@code Scrollable}
1948      */
1949     public Dimension getPreferredScrollableViewportSize() {
1950         return getPreferredSize();
1951     }
1952 
1953 
1954     /**
1955      * Components that display logical rows or columns should compute
1956      * the scroll increment that will completely expose one new row
1957      * or column, depending on the value of orientation.  Ideally,
1958      * components should handle a partially exposed row or column by
1959      * returning the distance required to completely expose the item.
1960      * <p>
1961      * The default implementation of this is to simply return 10% of
1962      * the visible area.  Subclasses are likely to be able to provide
1963      * a much more reasonable value.
1964      *
1965      * @param visibleRect the view area visible within the viewport
1966      * @param orientation either {@code SwingConstants.VERTICAL} or
1967      *   {@code SwingConstants.HORIZONTAL}
1968      * @param direction less than zero to scroll up/left, greater than
1969      *   zero for down/right
1970      * @return the "unit" increment for scrolling in the specified direction
1971      * @exception IllegalArgumentException for an invalid orientation
1972      * @see JScrollBar#setUnitIncrement
1973      */
1974     public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
1975         switch(orientation) {
1976         case SwingConstants.VERTICAL:
1977             return visibleRect.height / 10;
1978         case SwingConstants.HORIZONTAL:
1979             return visibleRect.width / 10;
1980         default:
1981             throw new IllegalArgumentException("Invalid orientation: " + orientation);
1982         }
1983     }
1984 
1985 
1986     /**
1987      * Components that display logical rows or columns should compute
1988      * the scroll increment that will completely expose one block
1989      * of rows or columns, depending on the value of orientation.
1990      * <p>
1991      * The default implementation of this is to simply return the visible
1992      * area.  Subclasses will likely be able to provide a much more
1993      * reasonable value.
1994      *
1995      * @param visibleRect the view area visible within the viewport
1996      * @param orientation either {@code SwingConstants.VERTICAL} or
1997      *   {@code SwingConstants.HORIZONTAL}
1998      * @param direction less than zero to scroll up/left, greater than zero
1999      *  for down/right
2000      * @return the "block" increment for scrolling in the specified direction
2001      * @exception IllegalArgumentException for an invalid orientation
2002      * @see JScrollBar#setBlockIncrement
2003      */
2004     public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
2005         switch(orientation) {
2006         case SwingConstants.VERTICAL:
2007             return visibleRect.height;
2008         case SwingConstants.HORIZONTAL:
2009             return visibleRect.width;
2010         default:
2011             throw new IllegalArgumentException("Invalid orientation: " + orientation);
2012         }
2013     }
2014 
2015 
2016     /**
2017      * Returns true if a viewport should always force the width of this
2018      * {@code Scrollable} to match the width of the viewport.
2019      * For example a normal text view that supported line wrapping
2020      * would return true here, since it would be undesirable for
2021      * wrapped lines to disappear beyond the right
2022      * edge of the viewport.  Note that returning true for a
2023      * {@code Scrollable} whose ancestor is a {@code JScrollPane}
2024      * effectively disables horizontal scrolling.
2025      * <p>
2026      * Scrolling containers, like {@code JViewport},
2027      * will use this method each time they are validated.
2028      *
2029      * @return true if a viewport should force the {@code Scrollable}s
2030      *   width to match its own
2031      */
2032     public boolean getScrollableTracksViewportWidth() {
2033         Container parent = SwingUtilities.getUnwrappedParent(this);
2034         if (parent instanceof JViewport) {
2035             return parent.getWidth() > getPreferredSize().width;
2036         }
2037         return false;
2038     }
2039 
2040     /**
2041      * Returns true if a viewport should always force the height of this
2042      * {@code Scrollable} to match the height of the viewport.
2043      * For example a columnar text view that flowed text in left to
2044      * right columns could effectively disable vertical scrolling by
2045      * returning true here.
2046      * <p>
2047      * Scrolling containers, like {@code JViewport},
2048      * will use this method each time they are validated.
2049      *
2050      * @return true if a viewport should force the Scrollables height
2051      *   to match its own
2052      */
2053     public boolean getScrollableTracksViewportHeight() {
2054         Container parent = SwingUtilities.getUnwrappedParent(this);
2055         if (parent instanceof JViewport) {
2056             return parent.getHeight() > getPreferredSize().height;
2057         }
2058         return false;
2059     }
2060 
2061 
2062 //////////////////
2063 // Printing Support
2064 //////////////////
2065 
2066     /**
2067      * A convenience print method that displays a print dialog, and then


2456      *
2457      * @see java.awt.print.Printable
2458      * @see java.awt.print.PageFormat
2459      * @see javax.swing.text.Document#render(java.lang.Runnable)
2460      *
2461      * @since 1.6
2462      */
2463     public Printable getPrintable(final MessageFormat headerFormat,
2464                                   final MessageFormat footerFormat) {
2465         return TextComponentPrintable.getPrintable(
2466                    this, headerFormat, footerFormat);
2467     }
2468 
2469 
2470 /////////////////
2471 // Accessibility support
2472 ////////////////
2473 
2474 
2475     /**
2476      * Gets the {@code AccessibleContext} associated with this
2477      * {@code JTextComponent}. For text components,
2478      * the {@code AccessibleContext} takes the form of an
2479      * {@code AccessibleJTextComponent}.
2480      * A new {@code AccessibleJTextComponent} instance
2481      * is created if necessary.
2482      *
2483      * @return an {@code AccessibleJTextComponent} that serves as the
2484      *         {@code AccessibleContext} of this
2485      *         {@code JTextComponent}
2486      */
2487     public AccessibleContext getAccessibleContext() {
2488         if (accessibleContext == null) {
2489             accessibleContext = new AccessibleJTextComponent();
2490         }
2491         return accessibleContext;
2492     }
2493 
2494     /**
2495      * This class implements accessibility support for the
2496      * {@code JTextComponent} class.  It provides an implementation of
2497      * the Java Accessibility API appropriate to menu user-interface elements.
2498      * <p>
2499      * <strong>Warning:</strong>
2500      * Serialized objects of this class will not be compatible with
2501      * future Swing releases. The current serialization support is
2502      * appropriate for short term storage or RMI between applications running
2503      * the same version of Swing.  As of 1.4, support for long term storage
2504      * of all JavaBeans&trade;
2505      * has been added to the {@code java.beans} package.
2506      * Please see {@link java.beans.XMLEncoder}.
2507      */
2508     @SuppressWarnings("serial") // Same-version serialization only
2509     public class AccessibleJTextComponent extends AccessibleJComponent
2510     implements AccessibleText, CaretListener, DocumentListener,
2511                AccessibleAction, AccessibleEditableText,
2512                AccessibleExtendedText {
2513 
2514         int caretPos;
2515         Point oldLocationOnScreen;
2516 
2517         /**
2518          * Constructs an AccessibleJTextComponent.  Adds a listener to track
2519          * caret change.
2520          */
2521         public AccessibleJTextComponent() {
2522             Document doc = JTextComponent.this.getDocument();
2523             if (doc != null) {
2524                 doc.addDocumentListener(this);
2525             }


2871          * Return 0 if the text is empty, or the caret position
2872          * if no selection.
2873          *
2874          * @return the index into the text of the end of the selection &ge; 0
2875          */
2876         public int getSelectionEnd() {
2877             return JTextComponent.this.getSelectionEnd();
2878         }
2879 
2880         /**
2881          * Returns the portion of the text that is selected.
2882          *
2883          * @return the text, null if no selection
2884          */
2885         public String getSelectedText() {
2886             return JTextComponent.this.getSelectedText();
2887         }
2888 
2889        /**
2890          * IndexedSegment extends Segment adding the offset into the
2891          * the model the {@code Segment} was asked for.
2892          */
2893         private class IndexedSegment extends Segment {
2894             /**
2895              * Offset into the model that the position represents.
2896              */
2897             public int modelOffset;
2898         }
2899 
2900 
2901         // TIGER - 4170173
2902         /**
2903          * Returns the String at a given index. Whitespace
2904          * between words is treated as a word.
2905          *
2906          * @param part the CHARACTER, WORD, or SENTENCE to retrieve
2907          * @param index an index within the text
2908          * @return the letter, word, or sentence.
2909          *
2910          */
2911         public String getAtIndex(int part, int index) {


2923          */
2924         public String getAfterIndex(int part, int index) {
2925             return getAtIndex(part, index, 1);
2926         }
2927 
2928 
2929         /**
2930          * Returns the String before a given index. Whitespace
2931          * between words is treated a word.
2932          *
2933          * @param part the CHARACTER, WORD, or SENTENCE to retrieve
2934          * @param index an index within the text
2935          * @return the letter, word, or sentence.
2936          */
2937         public String getBeforeIndex(int part, int index) {
2938             return getAtIndex(part, index, -1);
2939         }
2940 
2941 
2942         /**
2943          * Gets the word, sentence, or character at {@code index}.
2944          * If {@code direction} is non-null this will find the
2945          * next/previous word/sentence/character.
2946          */
2947         private String getAtIndex(int part, int index, int direction) {
2948             if (model instanceof AbstractDocument) {
2949                 ((AbstractDocument)model).readLock();
2950             }
2951             try {
2952                 if (index < 0 || index >= model.getLength()) {
2953                     return null;
2954                 }
2955                 switch (part) {
2956                 case AccessibleText.CHARACTER:
2957                     if (index + direction < model.getLength() &&
2958                         index + direction >= 0) {
2959                         return model.getText(index + direction, 1);
2960                     }
2961                     break;
2962 
2963 
2964                 case AccessibleText.WORD:


3010             if (model instanceof PlainDocument ) {
3011                 PlainDocument sdoc = (PlainDocument)model;
3012                 return sdoc.getParagraphElement(index);
3013             } else if (model instanceof StyledDocument) {
3014                 StyledDocument sdoc = (StyledDocument)model;
3015                 return sdoc.getParagraphElement(index);
3016             } else {
3017                 Element para;
3018                 for (para = model.getDefaultRootElement(); ! para.isLeaf(); ) {
3019                     int pos = para.getElementIndex(index);
3020                     para = para.getElement(pos);
3021                 }
3022                 if (para == null) {
3023                     return null;
3024                 }
3025                 return para.getParentElement();
3026             }
3027         }
3028 
3029         /*
3030          * Returns a {@code Segment} containing the paragraph text
3031          * at {@code index}, or null if {@code index} isn't
3032          * valid.
3033          */
3034         private IndexedSegment getParagraphElementText(int index)
3035                                   throws BadLocationException {
3036             Element para = getParagraphElement(index);
3037 
3038 
3039             if (para != null) {
3040                 IndexedSegment segment = new IndexedSegment();
3041                 try {
3042                     int length = para.getEndOffset() - para.getStartOffset();
3043                     model.getText(para.getStartOffset(), length, segment);
3044                 } catch (BadLocationException e) {
3045                     return null;
3046                 }
3047                 segment.modelOffset = para.getStartOffset();
3048                 return segment;
3049             }
3050             return null;
3051         }
3052 
3053 
3054         /**
3055          * Returns the Segment at {@code index} representing either
3056          * the paragraph or sentence as identified by {@code part}, or
3057          * null if a valid paragraph/sentence can't be found. The offset
3058          * will point to the start of the word/sentence in the array, and
3059          * the modelOffset will point to the location of the word/sentence
3060          * in the model.
3061          */
3062         private IndexedSegment getSegmentAt(int part, int index) throws
3063                                   BadLocationException {
3064             IndexedSegment seg = getParagraphElementText(index);
3065             if (seg == null) {
3066                 return null;
3067             }
3068             BreakIterator iterator;
3069             switch (part) {
3070             case AccessibleText.WORD:
3071                 iterator = BreakIterator.getWordInstance(getLocale());
3072                 break;
3073             case AccessibleText.SENTENCE:
3074                 iterator = BreakIterator.getSentenceInstance(getLocale());
3075                 break;
3076             default:


3255             Document doc = JTextComponent.this.getDocument();
3256             if (doc != null && doc instanceof StyledDocument) {
3257                 StyledDocument sDoc = (StyledDocument)doc;
3258                 int offset = startIndex;
3259                 int length = endIndex - startIndex;
3260                 sDoc.setCharacterAttributes(offset, length, as, true);
3261             }
3262         }
3263 
3264         // ----- end AccessibleEditableText methods
3265 
3266 
3267         // ----- begin AccessibleExtendedText methods
3268 
3269 // Probably should replace the helper method getAtIndex() to return
3270 // instead an AccessibleTextSequence also for LINE & ATTRIBUTE_RUN
3271 // and then make the AccessibleText methods get[At|After|Before]Point
3272 // call this new method instead and return only the string portion
3273 
3274         /**
3275          * Returns the AccessibleTextSequence at a given {@code index}.
3276          * If {@code direction} is non-null this will find the
3277          * next/previous word/sentence/character.
3278          *
3279          * @param part the {@code CHARACTER}, {@code WORD},
3280          * {@code SENTENCE}, {@code LINE} or
3281          * {@code ATTRIBUTE_RUN} to retrieve
3282          * @param index an index within the text
3283          * @param direction is either -1, 0, or 1
3284          * @return an {@code AccessibleTextSequence} specifying the text
3285          * if {@code part} and {@code index} are valid.  Otherwise,
3286          * {@code null} is returned.
3287          *
3288          * @see javax.accessibility.AccessibleText#CHARACTER
3289          * @see javax.accessibility.AccessibleText#WORD
3290          * @see javax.accessibility.AccessibleText#SENTENCE
3291          * @see javax.accessibility.AccessibleExtendedText#LINE
3292          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3293          *
3294          * @since 1.6
3295          */
3296         private AccessibleTextSequence getSequenceAtIndex(int part,
3297             int index, int direction) {
3298             if (index < 0 || index >= model.getLength()) {
3299                 return null;
3300             }
3301             if (direction < -1 || direction > 1) {
3302                 return null;    // direction must be 1, 0, or -1
3303             }
3304 
3305             switch (part) {
3306             case AccessibleText.CHARACTER:


3486                     // we are intentionally silent; our contract says we return
3487                     // null if there is any failure in this method
3488                     return null;
3489                 } finally {
3490                     if (model instanceof AbstractDocument) {
3491                         ((AbstractDocument)model).readUnlock();
3492                     }
3493                 }
3494                 return new AccessibleTextSequence(attributeRunStartIndex,
3495                                                   attributeRunEndIndex,
3496                                                   runText);
3497 
3498             default:
3499                 break;
3500             }
3501             return null;
3502         }
3503 
3504 
3505         /**
3506          * Starting at text position {@code index}, and going in
3507          * {@code direction}, return the edge of run that shares the
3508          * same {@code AttributeSet} and parent element as those at
3509          * {@code index}.
3510          *
3511          * Note: we assume the document is already locked...
3512          */
3513         private int getRunEdge(int index, int direction) throws
3514          BadLocationException {
3515             if (index < 0 || index >= model.getLength()) {
3516                 throw new BadLocationException("Location out of bounds", index);
3517             }
3518             // locate the Element at index
3519             Element indexElement;
3520             // locate the Element at our index/offset
3521             int elementIndex = -1;        // test for initialization
3522             for (indexElement = model.getDefaultRootElement();
3523                  ! indexElement.isLeaf(); ) {
3524                 elementIndex = indexElement.getElementIndex(index);
3525                 indexElement = indexElement.getElement(elementIndex);
3526             }
3527             if (elementIndex == -1) {
3528                 throw new AssertionError(index);
3529             }


3549                 edgeElement = parent.getElement(edgeElementIndex);
3550                 break;
3551             default:
3552                 throw new AssertionError(direction);
3553             }
3554             switch (direction) {
3555             case -1:
3556                 return edgeElement.getStartOffset();
3557             case 1:
3558                 return edgeElement.getEndOffset();
3559             default:
3560                 // we already caught this case earlier; this is to satisfy
3561                 // the compiler...
3562                 return Integer.MIN_VALUE;
3563             }
3564         }
3565 
3566         // getTextRange() not needed; defined in AccessibleEditableText
3567 
3568         /**
3569          * Returns the {@code AccessibleTextSequence} at a given
3570          * {@code index}.
3571          *
3572          * @param part the {@code CHARACTER}, {@code WORD},
3573          * {@code SENTENCE}, {@code LINE} or
3574          * {@code ATTRIBUTE_RUN} to retrieve
3575          * @param index an index within the text
3576          * @return an {@code AccessibleTextSequence} specifying the text if
3577          * {@code part} and {@code index} are valid.  Otherwise,
3578          * {@code null} is returned
3579          *
3580          * @see javax.accessibility.AccessibleText#CHARACTER
3581          * @see javax.accessibility.AccessibleText#WORD
3582          * @see javax.accessibility.AccessibleText#SENTENCE
3583          * @see javax.accessibility.AccessibleExtendedText#LINE
3584          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3585          *
3586          * @since 1.6
3587          */
3588         public AccessibleTextSequence getTextSequenceAt(int part, int index) {
3589             return getSequenceAtIndex(part, index, 0);
3590         }
3591 
3592         /**
3593          * Returns the {@code AccessibleTextSequence} after a given
3594          * {@code index}.
3595          *
3596          * @param part the {@code CHARACTER}, {@code WORD},
3597          * {@code SENTENCE}, {@code LINE} or
3598          * {@code ATTRIBUTE_RUN} to retrieve
3599          * @param index an index within the text
3600          * @return an {@code AccessibleTextSequence} specifying the text
3601          * if {@code part} and {@code index} are valid.  Otherwise,
3602          * {@code null} is returned
3603          *
3604          * @see javax.accessibility.AccessibleText#CHARACTER
3605          * @see javax.accessibility.AccessibleText#WORD
3606          * @see javax.accessibility.AccessibleText#SENTENCE
3607          * @see javax.accessibility.AccessibleExtendedText#LINE
3608          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3609          *
3610          * @since 1.6
3611          */
3612         public AccessibleTextSequence getTextSequenceAfter(int part, int index) {
3613             return getSequenceAtIndex(part, index, 1);
3614         }
3615 
3616         /**
3617          * Returns the {@code AccessibleTextSequence} before a given
3618          * {@code index}.
3619          *
3620          * @param part the {@code CHARACTER}, {@code WORD},
3621          * {@code SENTENCE}, {@code LINE} or
3622          * {@code ATTRIBUTE_RUN} to retrieve
3623          * @param index an index within the text
3624          * @return an {@code AccessibleTextSequence} specifying the text
3625          * if {@code part} and {@code index} are valid.  Otherwise,
3626          * {@code null} is returned
3627          *
3628          * @see javax.accessibility.AccessibleText#CHARACTER
3629          * @see javax.accessibility.AccessibleText#WORD
3630          * @see javax.accessibility.AccessibleText#SENTENCE
3631          * @see javax.accessibility.AccessibleExtendedText#LINE
3632          * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
3633          *
3634          * @since 1.6
3635          */
3636         public AccessibleTextSequence getTextSequenceBefore(int part, int index) {
3637             return getSequenceAtIndex(part, index, -1);
3638         }
3639 
3640         /**
3641          * Returns the {@code Rectangle} enclosing the text between
3642          * two indicies.
3643          *
3644          * @param startIndex the start index in the text
3645          * @param endIndex the end index in the text
3646          * @return the bounding rectangle of the text if the indices are valid.
3647          * Otherwise, {@code null} is returned
3648          *
3649          * @since 1.6
3650          */
3651         public Rectangle getTextBounds(int startIndex, int endIndex) {
3652             if (startIndex < 0 || startIndex > model.getLength()-1 ||
3653                 endIndex < 0 || endIndex > model.getLength()-1 ||
3654                 startIndex > endIndex) {
3655                 return null;
3656             }
3657             TextUI ui = getUI();
3658             if (ui == null) {
3659                 return null;
3660             }
3661             Rectangle rect = null;
3662             Rectangle alloc = getRootEditorRect();
3663             if (alloc == null) {
3664                 return null;
3665             }
3666             if (model instanceof AbstractDocument) {
3667                 ((AbstractDocument)model).readLock();


3834     private Color caretColor;
3835     private Color selectionColor;
3836     private Color selectedTextColor;
3837     private Color disabledTextColor;
3838     private boolean editable;
3839     private Insets margin;
3840     private char focusAccelerator;
3841     private boolean dragEnabled;
3842 
3843     /**
3844      * The drop mode for this component.
3845      */
3846     private DropMode dropMode = DropMode.USE_SELECTION;
3847 
3848     /**
3849      * The drop location.
3850      */
3851     private transient DropLocation dropLocation;
3852 
3853     /**
3854      * Represents a drop location for {@code JTextComponent}s.
3855      *
3856      * @see #getDropLocation
3857      * @since 1.6
3858      */
3859     public static final class DropLocation extends TransferHandler.DropLocation {
3860         private final int index;
3861         private final Position.Bias bias;
3862 
3863         private DropLocation(Point p, int index, Position.Bias bias) {
3864             super(p);
3865             this.index = index;
3866             this.bias = bias;
3867         }
3868 
3869         /**
3870          * Returns the index where dropped data should be inserted into the
3871          * associated component. This index represents a position between
3872          * characters, as would be interpreted by a caret.
3873          *
3874          * @return the drop index


3892          * and the content and format of the returned string may vary
3893          * between implementations.
3894          *
3895          * @return a string representation of this drop location
3896          */
3897         public String toString() {
3898             return getClass().getName()
3899                    + "[dropPoint=" + getDropPoint() + ","
3900                    + "index=" + index + ","
3901                    + "bias=" + bias + "]";
3902         }
3903     }
3904 
3905     /**
3906      * TransferHandler used if one hasn't been supplied by the UI.
3907      */
3908     private static DefaultTransferHandler defaultTransferHandler;
3909 
3910     /**
3911      * Maps from class name to Boolean indicating if
3912      * {@code processInputMethodEvent} has been overriden.
3913      */
3914     private static Cache<Class<?>,Boolean> METHOD_OVERRIDDEN
3915             = new Cache<Class<?>,Boolean>(Cache.Kind.WEAK, Cache.Kind.STRONG) {
3916         /**
3917          * Returns {@code true} if the specified {@code type} extends {@link JTextComponent}
3918          * and the {@link JTextComponent#processInputMethodEvent} method is overridden.
3919          */
3920         @Override
3921         public Boolean create(final Class<?> type) {
3922             if (JTextComponent.class == type) {
3923                 return Boolean.FALSE;
3924             }
3925             if (get(type.getSuperclass())) {
3926                 return Boolean.TRUE;
3927             }
3928             return AccessController.doPrivileged(
3929                     new PrivilegedAction<Boolean>() {
3930                         public Boolean run() {
3931                             try {
3932                                 type.getDeclaredMethod("processInputMethodEvent", InputMethodEvent.class);
3933                                 return Boolean.TRUE;
3934                             } catch (NoSuchMethodException exception) {
3935                                 return Boolean.FALSE;
3936                             }
3937                         }
3938                     });
3939         }
3940     };
3941 
3942     /**
3943      * Returns a string representation of this {@code JTextComponent}.
3944      * This method is intended to be used only for debugging purposes, and the
3945      * content and format of the returned string may vary between
3946      * implementations. The returned string may be empty but may not
3947      * be {@code null}.
3948      * <P>
3949      * Overriding {@code paramString} to provide information about the
3950      * specific new aspects of the JFC components.
3951      *
3952      * @return  a string representation of this {@code JTextComponent}
3953      */
3954     protected String paramString() {
3955         String editableString = (editable ?
3956                                  "true" : "false");
3957         String caretColorString = (caretColor != null ?
3958                                    caretColor.toString() : "");
3959         String selectionColorString = (selectionColor != null ?
3960                                        selectionColor.toString() : "");
3961         String selectedTextColorString = (selectedTextColor != null ?
3962                                           selectedTextColor.toString() : "");
3963         String disabledTextColorString = (disabledTextColor != null ?
3964                                           disabledTextColor.toString() : "");
3965         String marginString = (margin != null ?
3966                                margin.toString() : "");
3967 
3968         return super.paramString() +
3969         ",caretColor=" + caretColorString +
3970         ",disabledTextColor=" + disabledTextColorString +
3971         ",editable=" + editableString +
3972         ",margin=" + marginString +


4245          * String representation of the keymap... potentially
4246          * a very long string.
4247          */
4248         public String toString() {
4249             return "Keymap[" + nm + "]" + bindings;
4250         }
4251 
4252         String nm;
4253         Keymap parent;
4254         Hashtable<KeyStroke, Action> bindings;
4255         Action defaultAction;
4256     }
4257 
4258 
4259     /**
4260      * KeymapWrapper wraps a Keymap inside an InputMap. For KeymapWrapper
4261      * to be useful it must be used with a KeymapActionMap.
4262      * KeymapWrapper for the most part, is an InputMap with two parents.
4263      * The first parent visited is ALWAYS the Keymap, with the second
4264      * parent being the parent inherited from InputMap. If
4265      * {@code keymap.getAction} returns null, implying the Keymap
4266      * does not have a binding for the KeyStroke,
4267      * the parent is then visited. If the Keymap has a binding, the
4268      * Action is returned, if not and the KeyStroke represents a
4269      * KeyTyped event and the Keymap has a defaultAction,
4270      * {@code DefaultActionKey} is returned.
4271      * <p>KeymapActionMap is then able to transate the object passed in
4272      * to either message the Keymap, or message its default implementation.
4273      */
4274     static class KeymapWrapper extends InputMap {
4275         static final Object DefaultActionKey = new Object();
4276 
4277         private Keymap keymap;
4278 
4279         KeymapWrapper(Keymap keymap) {
4280             this.keymap = keymap;
4281         }
4282 
4283         public KeyStroke[] keys() {
4284             KeyStroke[] sKeys = super.keys();
4285             KeyStroke[] keymapKeys = keymap.getBoundKeyStrokes();
4286             int sCount = (sKeys == null) ? 0 : sKeys.length;
4287             int keymapCount = (keymapKeys == null) ? 0 : keymapKeys.length;
4288             if (sCount == 0) {
4289                 return keymapKeys;
4290             }


4308 
4309         public Object get(KeyStroke keyStroke) {
4310             Object retValue = keymap.getAction(keyStroke);
4311             if (retValue == null) {
4312                 retValue = super.get(keyStroke);
4313                 if (retValue == null &&
4314                     keyStroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED &&
4315                     keymap.getDefaultAction() != null) {
4316                     // Implies this is a KeyTyped event, use the default
4317                     // action.
4318                     retValue = DefaultActionKey;
4319                 }
4320             }
4321             return retValue;
4322         }
4323     }
4324 
4325 
4326     /**
4327      * Wraps a Keymap inside an ActionMap. This is used with
4328      * a KeymapWrapper. If {@code get} is passed in
4329      * {@code KeymapWrapper.DefaultActionKey}, the default action is
4330      * returned, otherwise if the key is an Action, it is returned.
4331      */
4332     static class KeymapActionMap extends ActionMap {
4333         private Keymap keymap;
4334 
4335         KeymapActionMap(Keymap keymap) {
4336             this.keymap = keymap;
4337         }
4338 
4339         public Object[] keys() {
4340             Object[] sKeys = super.keys();
4341             Object[] keymapKeys = keymap.getBoundActions();
4342             int sCount = (sKeys == null) ? 0 : sKeys.length;
4343             int keymapCount = (keymapKeys == null) ? 0 : keymapKeys.length;
4344             boolean hasDefault = (keymap.getDefaultAction() != null);
4345             if (hasDefault) {
4346                 keymapCount++;
4347             }
4348             if (sCount == 0) {
4349                 if (hasDefault) {


4393                 // Try the Keymap.
4394                 if (key == KeymapWrapper.DefaultActionKey) {
4395                     retValue = keymap.getDefaultAction();
4396                 }
4397                 else if (key instanceof Action) {
4398                     // This is a little iffy, technically an Action is
4399                     // a valid Key. We're assuming the Action came from
4400                     // the InputMap though.
4401                     retValue = (Action)key;
4402                 }
4403             }
4404             return retValue;
4405         }
4406     }
4407 
4408     private static final Object FOCUSED_COMPONENT =
4409         new StringBuilder("JTextComponent_FocusedComponent");
4410 
4411     /**
4412      * The default keymap that will be shared by all
4413      * {@code JTextComponent} instances unless they
4414      * have had a different keymap set.
4415      */
4416     public static final String DEFAULT_KEYMAP = "default";
4417 
4418     /**
4419      * Event to use when firing a notification of change to caret
4420      * position.  This is mutable so that the event can be reused
4421      * since caret events can be fairly high in bandwidth.
4422      */
4423     static class MutableCaretEvent extends CaretEvent implements ChangeListener, FocusListener, MouseListener {
4424 
4425         MutableCaretEvent(JTextComponent c) {
4426             super(c);
4427         }
4428 
4429         final void fire() {
4430             JTextComponent c = (JTextComponent) getSource();
4431             if (c != null) {
4432                 Caret caret = c.getCaret();
4433                 dot = caret.getDot();


< prev index next >