1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.java.swing.plaf.motif;
  26 
  27 import java.awt.*;
  28 import java.awt.event.*;
  29 
  30 import javax.swing.*;
  31 import javax.swing.text.*;
  32 import javax.swing.plaf.*;
  33 
  34 /**
  35  * Provides the look and feel features that are common across
  36  * the Motif/CDE text LAF implementations.
  37  * <p>
  38  * <strong>Warning:</strong>
  39  * Serialized objects of this class will not be compatible with
  40  * future Swing releases.  The current serialization support is appropriate
  41  * for short term storage or RMI between applications running the same
  42  * version of Swing.  A future release of Swing will provide support for
  43  * long term persistence.
  44  *
  45  * @author  Timothy Prinzing
  46  */
  47 public class MotifTextUI {
  48 
  49     /**
  50      * Creates the object to use for a caret for all of the Motif
  51      * text components.  The caret is rendered as an I-beam on Motif.
  52      *
  53      * @return the caret object
  54      */
  55     public static Caret createCaret() {
  56         return new MotifCaret();
  57     }
  58 
  59     /**
  60      * The motif caret is rendered as an I beam.
  61      * <p>
  62      * <strong>Warning:</strong>
  63      * Serialized objects of this class will not be compatible with
  64      * future Swing releases.  The current serialization support is appropriate
  65      * for short term storage or RMI between applications running the same
  66      * version of Swing.  A future release of Swing will provide support for
  67      * long term persistence.
  68      */
  69     @SuppressWarnings("serial") // Superclass is not serializable across versions
  70     public static class MotifCaret extends DefaultCaret implements UIResource {
  71 
  72         /**
  73          * Called when the component containing the caret gains
  74          * focus.  This is implemented to repaint the component
  75          * so the focus rectangle will be re-rendered, as well
  76          * as providing the superclass behavior.
  77          *
  78          * @param e the focus event
  79          * @see FocusListener#focusGained
  80          */
  81         public void focusGained(FocusEvent e) {
  82             super.focusGained(e);
  83             getComponent().repaint();
  84         }
  85 
  86         /**
  87          * Called when the component containing the caret loses
  88          * focus.  This is implemented to set the caret to visibility
  89          * to false.
  90          *
  91          * @param e the focus event
  92          * @see FocusListener#focusLost
  93          */
  94         public void focusLost(FocusEvent e) {
  95             super.focusLost(e);
  96             getComponent().repaint();
  97         }
  98 
  99         /**
 100          * Damages the area surrounding the caret to cause
 101          * it to be repainted.  If paint() is reimplemented,
 102          * this method should also be reimplemented.
 103          *
 104          * @param r  the current location of the caret, does nothing if null
 105          * @see #paint
 106          */
 107         protected void damage(Rectangle r) {
 108             if (r != null) {
 109                 x = r.x - IBeamOverhang - 1;
 110                 y = r.y;
 111                 width = r.width + (2 * IBeamOverhang) + 3;
 112                 height = r.height;
 113                 repaint();
 114             }
 115         }
 116 
 117         /**
 118          * Renders the caret as a vertical line.  If this is reimplemented
 119          * the damage method should also be reimplemented as it assumes the
 120          * shape of the caret is a vertical line.  Does nothing if isVisible()
 121          * is false.  The caret color is derived from getCaretColor() if
 122          * the component has focus, else from getDisabledTextColor().
 123          *
 124          * @param g the graphics context
 125          * @see #damage
 126          */
 127         @SuppressWarnings("deprecation")
 128         public void paint(Graphics g) {
 129             if(isVisible()) {
 130                 try {
 131                     JTextComponent c = getComponent();
 132                     Color fg = c.hasFocus() ? c.getCaretColor() :
 133                         c.getDisabledTextColor();
 134                     TextUI mapper = c.getUI();
 135                     int dot = getDot();
 136                     Rectangle r = mapper.modelToView(c, dot);
 137                     int x0 = r.x - IBeamOverhang;
 138                     int x1 = r.x + IBeamOverhang;
 139                     int y0 = r.y + 1;
 140                     int y1 = r.y + r.height - 2;
 141                     g.setColor(fg);
 142                     g.drawLine(r.x, y0, r.x, y1);
 143                     g.drawLine(x0, y0, x1, y0);
 144                     g.drawLine(x0, y1, x1, y1);
 145                 } catch (BadLocationException e) {
 146                     // can't render I guess
 147                     //System.err.println("Can't render caret");
 148                 }
 149             }
 150         }
 151 
 152         static final int IBeamOverhang = 2;
 153     }
 154 
 155     /**
 156      * Default bindings all keymaps implementing the Motif feel.
 157      */
 158     @SuppressWarnings("deprecation")
 159     static final JTextComponent.KeyBinding[] defaultBindings = {
 160         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,
 161                                                                     InputEvent.CTRL_MASK),
 162                                              DefaultEditorKit.copyAction),
 163         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,
 164                                                                     InputEvent.SHIFT_MASK),
 165                                              DefaultEditorKit.pasteAction),
 166         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,
 167                                                                     InputEvent.SHIFT_MASK),
 168                                              DefaultEditorKit.cutAction),
 169         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
 170                                                                     InputEvent.SHIFT_MASK),
 171                                              DefaultEditorKit.selectionBackwardAction),
 172         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
 173                                                                     InputEvent.SHIFT_MASK),
 174                                              DefaultEditorKit.selectionForwardAction),
 175     };
 176 
 177 
 178 }