1 /*
   2  * Copyright (c) 2002, 2010, 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 
  26 package javax.swing.plaf.synth;
  27 
  28 import javax.swing.*;
  29 import javax.swing.text.*;
  30 import javax.swing.plaf.*;
  31 import java.beans.PropertyChangeEvent;
  32 import java.awt.*;
  33 
  34 /**
  35  * Provides the look and feel for a styled text editor in the
  36  * Synth look and feel.
  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
  41  * appropriate for short term storage or RMI between applications running
  42  * the same version of Swing.  As of 1.4, support for long term storage
  43  * of all JavaBeans<sup><font size="-2">TM</font></sup>
  44  * has been added to the <code>java.beans</code> package.
  45  * Please see {@link java.beans.XMLEncoder}.
  46  *
  47  * @author  Shannon Hickey
  48  * @since 1.7
  49  */
  50 public class SynthTextPaneUI extends SynthEditorPaneUI {
  51 
  52     /**
  53      * Creates a UI for the JTextPane.
  54      *
  55      * @param c the JTextPane object
  56      * @return the UI object
  57      */
  58     public static ComponentUI createUI(JComponent c) {
  59         return new SynthTextPaneUI();
  60     }
  61 
  62     /**
  63      * Fetches the name used as a key to lookup properties through the
  64      * UIManager.  This is used as a prefix to all the standard
  65      * text properties.
  66      *
  67      * @return the name ("TextPane")
  68      */
  69     @Override
  70     protected String getPropertyPrefix() {
  71         return "TextPane";
  72     }
  73 
  74     /**
  75      * Installs the UI for a component.  This does the following
  76      * things.
  77      * <ol>
  78      * <li>
  79      * Sets opaqueness of the associated component according to its style,
  80      * if the opaque property has not already been set by the client program.
  81      * <li>
  82      * Installs the default caret and highlighter into the
  83      * associated component. These properties are only set if their
  84      * current value is either {@code null} or an instance of
  85      * {@link UIResource}.
  86      * <li>
  87      * Attaches to the editor and model.  If there is no
  88      * model, a default one is created.
  89      * <li>
  90      * Creates the view factory and the view hierarchy used
  91      * to represent the model.
  92      * </ol>
  93      *
  94      * @param c the editor component
  95      * @see BasicTextUI#installUI
  96      * @see ComponentUI#installUI
  97      */
  98     @Override
  99     public void installUI(JComponent c) {
 100         super.installUI(c);
 101         updateForeground(c.getForeground());
 102         updateFont(c.getFont());
 103     }
 104 
 105     /**
 106      * This method gets called when a bound property is changed
 107      * on the associated JTextComponent.  This is a hook
 108      * which UI implementations may change to reflect how the
 109      * UI displays bound properties of JTextComponent subclasses.
 110      * If the font, foreground or document has changed, the
 111      * the appropriate property is set in the default style of
 112      * the document.
 113      *
 114      * @param evt the property change event
 115      */
 116     @Override
 117     protected void propertyChange(PropertyChangeEvent evt) {
 118         super.propertyChange(evt);
 119 
 120         String name = evt.getPropertyName();
 121 
 122         if (name.equals("foreground")) {
 123             updateForeground((Color)evt.getNewValue());
 124         } else if (name.equals("font")) {
 125             updateFont((Font)evt.getNewValue());
 126         } else if (name.equals("document")) {
 127             JComponent comp = getComponent();
 128             updateForeground(comp.getForeground());
 129             updateFont(comp.getFont());
 130         }
 131     }
 132 
 133     /**
 134      * Update the color in the default style of the document.
 135      *
 136      * @param color the new color to use or null to remove the color attribute
 137      *              from the document's style
 138      */
 139     private void updateForeground(Color color) {
 140         StyledDocument doc = (StyledDocument)getComponent().getDocument();
 141         Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
 142 
 143         if (style == null) {
 144             return;
 145         }
 146 
 147         if (color == null) {
 148             style.removeAttribute(StyleConstants.Foreground);
 149         } else {
 150             StyleConstants.setForeground(style, color);
 151         }
 152     }
 153 
 154     /**
 155      * Update the font in the default style of the document.
 156      *
 157      * @param font the new font to use or null to remove the font attribute
 158      *             from the document's style
 159      */
 160     private void updateFont(Font font) {
 161         StyledDocument doc = (StyledDocument)getComponent().getDocument();
 162         Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
 163 
 164         if (style == null) {
 165             return;
 166         }
 167 
 168         if (font == null) {
 169             style.removeAttribute(StyleConstants.FontFamily);
 170             style.removeAttribute(StyleConstants.FontSize);
 171             style.removeAttribute(StyleConstants.Bold);
 172             style.removeAttribute(StyleConstants.Italic);
 173         } else {
 174             StyleConstants.setFontFamily(style, font.getName());
 175             StyleConstants.setFontSize(style, font.getSize());
 176             StyleConstants.setBold(style, font.isBold());
 177             StyleConstants.setItalic(style, font.isItalic());
 178         }
 179     }
 180 
 181     @Override
 182     void paintBackground(SynthContext context, Graphics g, JComponent c) {
 183         context.getPainter().paintTextPaneBackground(context, g, 0, 0,
 184                                                   c.getWidth(), c.getHeight());
 185     }
 186 
 187     /**
 188      * @inheritDoc
 189      */
 190     @Override
 191     public void paintBorder(SynthContext context, Graphics g, int x,
 192                             int y, int w, int h) {
 193         context.getPainter().paintTextPaneBorder(context, g, x, y, w, h);
 194     }
 195 }