gt:                         a = map.get(DefaultEditorKit.selectLineAction);
context: /*
   * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  package javax.swing.text;
  
  import java.awt.*;
  import java.awt.event.*;
  import java.awt.datatransfer.*;
  import java.beans.*;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.*;
  import javax.swing.*;
  import javax.swing.event.*;
  import javax.swing.plaf.*;
  import java.util.EventListener;
  import sun.swing.SwingUtilities2;
  
  /**
   * A default implementation of Caret.  The caret is rendered as
   * a vertical line in the color specified by the CaretColor property
   * of the associated JTextComponent.  It can blink at the rate specified
   * by the BlinkRate property.
   * <p>
   * This implementation expects two sources of asynchronous notification.
   * The timer thread fires asynchronously, and causes the caret to simply
   * repaint the most recent bounding box.  The caret also tracks change
   * as the document is modified.  Typically this will happen on the
   * event dispatch thread as a result of some mouse or keyboard event.
   * The caret behavior on both synchronous and asynchronous documents updates
   * is controlled by <code>UpdatePolicy</code> property. The repaint of the
   * new caret location will occur on the event thread in any case, as calls to
   * <code>modelToView</code> are only safe on the event thread.
   * <p>
   * The caret acts as a mouse and focus listener on the text component
   * it has been installed in, and defines the caret semantics based upon
   * those events.  The listener methods can be reimplemented to change the
   * semantics.
   * By default, the first mouse button will be used to set focus and caret
   * position.  Dragging the mouse pointer with the first mouse button will
   * sweep out a selection that is contiguous in the model.  If the associated
   * text component is editable, the caret will become visible when focus
   * is gained, and invisible when focus is lost.
   * <p>
   * The Highlighter bound to the associated text component is used to
   * render the selection by default.
   * Selection appearance can be customized by supplying a
   * painter to use for the highlights.  By default a painter is used that
   * will render a solid color as specified in the associated text component
   * in the <code>SelectionColor</code> property.  This can easily be changed
   * by reimplementing the
   * {@link #getSelectionPainter getSelectionPainter}
   * method.
   * <p>
   * A customized caret appearance can be achieved by reimplementing
   * the paint method.  If the paint method is changed, the damage method
   * should also be reimplemented to cause a repaint for the area needed
   * to render the caret.  The caret extends the Rectangle class which
   * is used to hold the bounding box for where the caret was last rendered.
   * This enables the caret to repaint in a thread-safe manner when the
   * caret moves without making a call to modelToView which is unstable
   * between model updates and view repair (i.e. the order of delivery
   * to DocumentListeners is not guaranteed).
   * <p>
   * The magic caret position is set to null when the caret position changes.
   * A timer is used to determine the new location (after the caret change).
   * When the timer fires, if the magic caret position is still null it is
   * reset to the current caret position. Any actions that change
   * the caret position and want the magic caret position to remain the
   * same, must remember the magic caret position, change the cursor, and
   * then set the magic caret position to its original value. This has the
   * benefit that only actions that want the magic caret position to persist
   * (such as open/down) need to know about it.
   * <p>
   * <strong>Warning:</strong>
   * Serialized objects of this class will not be compatible with
   * future Swing releases. The current serialization support is
   * appropriate for short term storage or RMI between applications running
   * the same version of Swing.  As of 1.4, support for long term storage
   * of all JavaBeans&trade;
   * has been added to the <code>java.beans</code> package.
   * Please see {@link java.beans.XMLEncoder}.
   *
   * @author  Timothy Prinzing
   * @see     Caret
   */
  @SuppressWarnings("serial") // Same-version serialization only
  public class DefaultCaret extends Rectangle implements Caret, FocusListener, MouseListener, MouseMotionListener {
  
      /**
       * Indicates that the caret position is to be updated only when
       * document changes are performed on the Event Dispatching Thread.
       * @see #setUpdatePolicy
       * @see #getUpdatePolicy
       * @since 1.5
       */
      public static final int UPDATE_WHEN_ON_EDT = 0;
  
      /**
       * Indicates that the caret should remain at the same
       * absolute position in the document regardless of any document
       * updates, except when the document length becomes less than
       * the current caret position due to removal. In that case the caret
       * position is adjusted to the end of the document.
       *
       * @see #setUpdatePolicy
       * @see #getUpdatePolicy
       * @since 1.5
       */
      public static final int NEVER_UPDATE = 1;
  
      /**
       * Indicates that the caret position is to be <b>always</b>
       * updated accordingly to the document changes regardless whether
       * the document updates are performed on the Event Dispatching Thread
       * or not.
       *
       * @see #setUpdatePolicy
       * @see #getUpdatePolicy
       * @since 1.5
       */
      public static final int ALWAYS_UPDATE = 2;
  
      /**
       * Constructs a default caret.
       */
      public DefaultCaret() {
      }
  
      /**
       * Sets the caret movement policy on the document updates. Normally
       * the caret updates its absolute position within the document on
       * insertions occurred before or at the caret position and
       * on removals before the caret position. 'Absolute position'
       * means here the position relative to the start of the document.
       * For example if
       * a character is typed within editable text component it is inserted
       * at the caret position and the caret moves to the next absolute
       * position within the document due to insertion and if
       * <code>BACKSPACE</code> is typed then caret decreases its absolute
       * position due to removal of a character before it. Sometimes
       * it may be useful to turn off the caret position updates so that
       * the caret stays at the same absolute position within the
       * document position regardless of any document updates.
       * <p>
       * The following update policies are allowed:
       * <ul>
       *   <li><code>NEVER_UPDATE</code>: the caret stays at the same
       *       absolute position in the document regardless of any document
       *       updates, except when document length becomes less than
       *       the current caret position due to removal. In that case caret
       *       position is adjusted to the end of the document.
       *       The caret doesn't try to keep itself visible by scrolling
       *       the associated view when using this policy. </li>
       *   <li><code>ALWAYS_UPDATE</code>: the caret always tracks document
       *       changes. For regular changes it increases its position
       *       if an insertion occurs before or at its current position,
       *       and decreases position if a removal occurs before
       *       its current position. For undo/redo updates it is always
       *       moved to the position where update occurred. The caret
       *       also tries to keep itself visible by calling
       *       <code>adjustVisibility</code> method.</li>
       *   <li><code>UPDATE_WHEN_ON_EDT</code>: acts like <code>ALWAYS_UPDATE</code>
       *       if the document updates are performed on the Event Dispatching Thread
       *       and like <code>NEVER_UPDATE</code> if updates are performed on
       *       other thread. </li>
       * </ul> <p>
       * The default property value is <code>UPDATE_WHEN_ON_EDT</code>.
       *
       * @param policy one of the following values : <code>UPDATE_WHEN_ON_EDT</code>,
       * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code>
       * @throws IllegalArgumentException if invalid value is passed
       *
       * @see #getUpdatePolicy
       * @see #adjustVisibility
       * @see #UPDATE_WHEN_ON_EDT
       * @see #NEVER_UPDATE
       * @see #ALWAYS_UPDATE
       *
       * @since 1.5
       */
      public void setUpdatePolicy(int policy) {
          updatePolicy = policy;
      }
  
      /**
       * Gets the caret movement policy on document updates.
       *
       * @return one of the following values : <code>UPDATE_WHEN_ON_EDT</code>,
       * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code>
       *
       * @see #setUpdatePolicy
       * @see #UPDATE_WHEN_ON_EDT
       * @see #NEVER_UPDATE
       * @see #ALWAYS_UPDATE
       *
       * @since 1.5
       */
      public int getUpdatePolicy() {
          return updatePolicy;
      }
  
      /**
       * Gets the text editor component that this caret is
       * is bound to.
       *
       * @return the component
       */
      protected final JTextComponent getComponent() {
          return component;
      }
  
      /**
       * Cause the caret to be painted.  The repaint
       * area is the bounding box of the caret (i.e.
       * the caret rectangle or <em>this</em>).
       * <p>
       * This method is thread safe, although most Swing methods
       * are not. Please see
       * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
       * in Swing</A> for more information.
       */
      protected final synchronized void repaint() {
          if (component != null) {
              component.repaint(x, y, width, height);
          }
      }
  
      /**
       * Damages the area surrounding the caret to cause
       * it to be repainted in a new location.  If paint()
       * is reimplemented, this method should also be
       * reimplemented.  This method should update the
       * caret bounds (x, y, width, and height).
       *
       * @param r  the current location of the caret
       * @see #paint
       */
      protected synchronized void damage(Rectangle r) {
          if (r != null) {
              int damageWidth = getCaretWidth(r.height);
              x = r.x - 4 - (damageWidth >> 1);
              y = r.y;
              width = 9 + damageWidth;
              height = r.height;
              repaint();
          }
      }
  
      /**
       * Scrolls the associated view (if necessary) to make
       * the caret visible.  Since how this should be done
       * is somewhat of a policy, this method can be
       * reimplemented to change the behavior.  By default
       * the scrollRectToVisible method is called on the
       * associated component.
       *
       * @param nloc the new position to scroll to
       */
      protected void adjustVisibility(Rectangle nloc) {
          if(component == null) {
              return;
          }
          if (SwingUtilities.isEventDispatchThread()) {
                  component.scrollRectToVisible(nloc);
          } else {
              SwingUtilities.invokeLater(new SafeScroller(nloc));
          }
      }
  
      /**
       * Gets the painter for the Highlighter.
       *
       * @return the painter
       */
      protected Highlighter.HighlightPainter getSelectionPainter() {
          return DefaultHighlighter.DefaultPainter;
      }
  
      /**
       * Tries to set the position of the caret from
       * the coordinates of a mouse event, using viewToModel().
       *
       * @param e the mouse event
       */
      protected void positionCaret(MouseEvent e) {
          Point pt = new Point(e.getX(), e.getY());
          Position.Bias[] biasRet = new Position.Bias[1];
          int pos = component.getUI().viewToModel(component, pt, biasRet);
          if(biasRet[0] == null)
              biasRet[0] = Position.Bias.Forward;
          if (pos >= 0) {
              setDot(pos, biasRet[0]);
          }
      }
  
      /**
       * Tries to move the position of the caret from
       * the coordinates of a mouse event, using viewToModel().
       * This will cause a selection if the dot and mark
       * are different.
       *
       * @param e the mouse event
       */
      protected void moveCaret(MouseEvent e) {
          Point pt = new Point(e.getX(), e.getY());
          Position.Bias[] biasRet = new Position.Bias[1];
          int pos = component.getUI().viewToModel(component, pt, biasRet);
          if(biasRet[0] == null)
              biasRet[0] = Position.Bias.Forward;
          if (pos >= 0) {
              moveDot(pos, biasRet[0]);
          }
      }
  
      // --- FocusListener methods --------------------------
  
      /**
       * Called when the component containing the caret gains
       * focus.  This is implemented to set the caret to visible
       * if the component is editable.
       *
       * @param e the focus event
       * @see FocusListener#focusGained
       */
      public void focusGained(FocusEvent e) {
          if (component.isEnabled()) {
              if (component.isEditable()) {
                  setVisible(true);
              }
              setSelectionVisible(true);
          }
      }
  
      /**
       * Called when the component containing the caret loses
       * focus.  This is implemented to set the caret to visibility
       * to false.
       *
       * @param e the focus event
       * @see FocusListener#focusLost
       */
      public void focusLost(FocusEvent e) {
          setVisible(false);
          setSelectionVisible(ownsSelection || e.isTemporary());
      }
  
  
      /**
       * Selects word based on the MouseEvent
       */
      private void selectWord(MouseEvent e) {
          if (selectedWordEvent != null
              && selectedWordEvent.getX() == e.getX()
              && selectedWordEvent.getY() == e.getY()) {
              //we already done selection for this
              return;
          }
                      Action a = null;
                      ActionMap map = getComponent().getActionMap();
                      if (map != null) {
                          a = map.get(DefaultEditorKit.selectWordAction);
                      }
                      if (a == null) {
                          if (selectWord == null) {
                              selectWord = new DefaultEditorKit.SelectWordAction();
                          }
                          a = selectWord;
                      }
                      a.actionPerformed(new ActionEvent(getComponent(),
                                                        ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers()));
          selectedWordEvent = e;
      }
  
      // --- MouseListener methods -----------------------------------
  
      /**
       * Called when the mouse is clicked.  If the click was generated
       * from button1, a double click selects a word,
       * and a triple click the current line.
       *
       * @param e the mouse event
       * @see MouseListener#mouseClicked
       */
      public void mouseClicked(MouseEvent e) {
          if (getComponent() == null) {
              return;
          }
  
          int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e);
  
          if (! e.isConsumed()) {
              if (SwingUtilities.isLeftMouseButton(e)) {
                  // mouse 1 behavior
                  if(nclicks == 1) {
                      selectedWordEvent = null;
                  } else if(nclicks == 2
                            && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                      selectWord(e);
                      selectedWordEvent = null;
                  } else if(nclicks == 3
                            && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                      Action a = null;
                      ActionMap map = getComponent().getActionMap();
                      if (map != null) {
  