Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2006, 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 javax.swing.plaf.basic;
   26   
   27   import java.awt;
   28   import java.awt.event;
   29   import java.beans;
   30   import java.net.URL;
   31   import java.net.MalformedURLException;
   32   import javax.swing;
   33   import javax.swing.text;
   34   import javax.swing.text.html;
   35   import javax.swing.plaf;
   36   import javax.swing.border;
   37   
   38   
   39   /**
   40    * Provides the look and feel for a JEditorPane.
   41    * <p>
   42    * <strong>Warning:</strong>
   43    * Serialized objects of this class will not be compatible with
   44    * future Swing releases. The current serialization support is
   45    * appropriate for short term storage or RMI between applications running
   46    * the same version of Swing.  As of 1.4, support for long term storage
   47    * of all JavaBeans<sup><font size="-2">TM</font></sup>
   48    * has been added to the <code>java.beans</code> package.
   49    * Please see {@link java.beans.XMLEncoder}.
   50    *
   51    * @author  Timothy Prinzing
   52    */
   53   public class BasicEditorPaneUI extends BasicTextUI {
   54   
   55       /**
   56        * Creates a UI for the JTextPane.
   57        *
   58        * @param c the JTextPane component
   59        * @return the UI
   60        */
   61       public static ComponentUI createUI(JComponent c) {
   62           return new BasicEditorPaneUI();
   63       }
   64   
   65       /**
   66        * Creates a new BasicEditorPaneUI.
   67        */
   68       public BasicEditorPaneUI() {
   69           super();
   70       }
   71   
   72       /**
   73        * Fetches the name used as a key to lookup properties through the
   74        * UIManager.  This is used as a prefix to all the standard
   75        * text properties.
   76        *
   77        * @return the name ("EditorPane")
   78        */
   79       protected String getPropertyPrefix() {
   80           return "EditorPane";
   81       }
   82   
   83       /**
   84        *{@inheritDoc}
   85        *
   86        * @since 1.5
   87        */
   88       public void installUI(JComponent c) {
   89           super.installUI(c);
   90           updateDisplayProperties(c.getFont(),
   91                                   c.getForeground());
   92       }
   93   
   94       /**
   95        *{@inheritDoc}
   96        *
   97        * @since 1.5
   98        */
   99       public void uninstallUI(JComponent c) {
  100           cleanDisplayProperties();
  101           super.uninstallUI(c);
  102       }
  103   
  104       /**
  105        * Fetches the EditorKit for the UI.  This is whatever is
  106        * currently set in the associated JEditorPane.
  107        *
  108        * @return the editor capabilities
  109        * @see TextUI#getEditorKit
  110        */
  111       public EditorKit getEditorKit(JTextComponent tc) {
  112           JEditorPane pane = (JEditorPane) getComponent();
  113           return pane.getEditorKit();
  114       }
  115   
  116       /**
  117        * Fetch an action map to use.  The map for a JEditorPane
  118        * is not shared because it changes with the EditorKit.
  119        */
  120       ActionMap getActionMap() {
  121           ActionMap am = new ActionMapUIResource();
  122           am.put("requestFocus", new FocusAction());
  123           EditorKit editorKit = getEditorKit(getComponent());
  124           if (editorKit != null) {
  125               Action[] actions = editorKit.getActions();
  126               if (actions != null) {
  127                   addActions(am, actions);
  128               }
  129           }
  130           am.put(TransferHandler.getCutAction().getValue(Action.NAME),
  131                   TransferHandler.getCutAction());
  132           am.put(TransferHandler.getCopyAction().getValue(Action.NAME),
  133                   TransferHandler.getCopyAction());
  134           am.put(TransferHandler.getPasteAction().getValue(Action.NAME),
  135                   TransferHandler.getPasteAction());
  136           return am;
  137       }
  138   
  139       /**
  140        * This method gets called when a bound property is changed
  141        * on the associated JTextComponent.  This is a hook
  142        * which UI implementations may change to reflect how the
  143        * UI displays bound properties of JTextComponent subclasses.
  144        * This is implemented to rebuild the ActionMap based upon an
  145        * EditorKit change.
  146        *
  147        * @param evt the property change event
  148        */
  149       protected void propertyChange(PropertyChangeEvent evt) {
  150           super.propertyChange(evt);
  151           String name = evt.getPropertyName();
  152           if ("editorKit".equals(name)) {
  153               ActionMap map = SwingUtilities.getUIActionMap(getComponent());
  154               if (map != null) {
  155                   Object oldValue = evt.getOldValue();
  156                   if (oldValue instanceof EditorKit) {
  157                       Action[] actions = ((EditorKit)oldValue).getActions();
  158                       if (actions != null) {
  159                           removeActions(map, actions);
  160                       }
  161                   }
  162                   Object newValue = evt.getNewValue();
  163                   if (newValue instanceof EditorKit) {
  164                       Action[] actions = ((EditorKit)newValue).getActions();
  165                       if (actions != null) {
  166                           addActions(map, actions);
  167                       }
  168                   }
  169               }
  170               updateFocusTraversalKeys();
  171           } else if ("editable".equals(name)) {
  172               updateFocusTraversalKeys();
  173           } else if ("foreground".equals(name)
  174                      || "font".equals(name)
  175                      || "document".equals(name)
  176                      || JEditorPane.W3C_LENGTH_UNITS.equals(name)
  177                      || JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name)
  178                      ) {
  179               JComponent c = getComponent();
  180               updateDisplayProperties(c.getFont(), c.getForeground());
  181               if ( JEditorPane.W3C_LENGTH_UNITS.equals(name)
  182                    || JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name) ) {
  183                   modelChanged();
  184               }
  185               if ("foreground".equals(name)) {
  186                   Object honorDisplayPropertiesObject = c.
  187                       getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
  188                   boolean honorDisplayProperties = false;
  189                   if (honorDisplayPropertiesObject instanceof Boolean) {
  190                       honorDisplayProperties =
  191                           ((Boolean)honorDisplayPropertiesObject).booleanValue();
  192                   }
  193                   if (honorDisplayProperties) {
  194                       modelChanged();
  195                   }
  196               }
  197   
  198   
  199           }
  200       }
  201   
  202       void removeActions(ActionMap map, Action[] actions) {
  203           int n = actions.length;
  204           for (int i = 0; i < n; i++) {
  205               Action a = actions[i];
  206               map.remove(a.getValue(Action.NAME));
  207           }
  208       }
  209   
  210       void addActions(ActionMap map, Action[] actions) {
  211           int n = actions.length;
  212           for (int i = 0; i < n; i++) {
  213               Action a = actions[i];
  214               map.put(a.getValue(Action.NAME), a);
  215           }
  216       }
  217   
  218       void updateDisplayProperties(Font font, Color fg) {
  219           JComponent c = getComponent();
  220           Object honorDisplayPropertiesObject = c.
  221               getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
  222           boolean honorDisplayProperties = false;
  223           Object w3cLengthUnitsObject = c.getClientProperty(JEditorPane.
  224                                                             W3C_LENGTH_UNITS);
  225           boolean w3cLengthUnits = false;
  226           if (honorDisplayPropertiesObject instanceof Boolean) {
  227               honorDisplayProperties =
  228                   ((Boolean)honorDisplayPropertiesObject).booleanValue();
  229           }
  230           if (w3cLengthUnitsObject instanceof Boolean) {
  231               w3cLengthUnits = ((Boolean)w3cLengthUnitsObject).booleanValue();
  232           }
  233           if (this instanceof BasicTextPaneUI
  234               || honorDisplayProperties) {
  235                //using equals because can not use UIResource for Boolean
  236               Document doc = getComponent().getDocument();
  237               if (doc instanceof StyledDocument) {
  238                   if (doc instanceof HTMLDocument
  239                       && honorDisplayProperties) {
  240                       updateCSS(font, fg);
  241                   } else {
  242                       updateStyle(font, fg);
  243                   }
  244               }
  245           } else {
  246               cleanDisplayProperties();
  247           }
  248           if ( w3cLengthUnits ) {
  249               Document doc = getComponent().getDocument();
  250               if (doc instanceof HTMLDocument) {
  251                   StyleSheet documentStyleSheet =
  252                       ((HTMLDocument)doc).getStyleSheet();
  253                   documentStyleSheet.addRule("W3C_LENGTH_UNITS_ENABLE");
  254               }
  255           } else {
  256               Document doc = getComponent().getDocument();
  257               if (doc instanceof HTMLDocument) {
  258                   StyleSheet documentStyleSheet =
  259                       ((HTMLDocument)doc).getStyleSheet();
  260                   documentStyleSheet.addRule("W3C_LENGTH_UNITS_DISABLE");
  261               }
  262   
  263           }
  264       }
  265   
  266       /**
  267        * Attribute key to reference the default font.
  268        * used in javax.swing.text.StyleContext.getFont
  269        * to resolve the default font.
  270        */
  271       private static final String FONT_ATTRIBUTE_KEY = "FONT_ATTRIBUTE_KEY";
  272   
  273       void cleanDisplayProperties() {
  274           Document document = getComponent().getDocument();
  275           if (document instanceof HTMLDocument) {
  276               StyleSheet documentStyleSheet =
  277                   ((HTMLDocument)document).getStyleSheet();
  278               StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
  279               if (styleSheets != null) {
  280                   for (StyleSheet s : styleSheets) {
  281                       if (s instanceof StyleSheetUIResource) {
  282                           documentStyleSheet.removeStyleSheet(s);
  283                           documentStyleSheet.addRule("BASE_SIZE_DISABLE");
  284                           break;
  285                       }
  286                   }
  287               }
  288               Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
  289               if (style.getAttribute(FONT_ATTRIBUTE_KEY) != null) {
  290                   style.removeAttribute(FONT_ATTRIBUTE_KEY);
  291               }
  292           }
  293       }
  294   
  295       static class StyleSheetUIResource extends StyleSheet implements UIResource {
  296       }
  297   
  298       private void updateCSS(Font font, Color fg) {
  299           JTextComponent component = getComponent();
  300           Document document = component.getDocument();
  301           if (document instanceof HTMLDocument) {
  302               StyleSheet styleSheet = new StyleSheetUIResource();
  303               StyleSheet documentStyleSheet =
  304                   ((HTMLDocument)document).getStyleSheet();
  305               StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
  306               if (styleSheets != null) {
  307                   for (StyleSheet s : styleSheets) {
  308                       if (s instanceof StyleSheetUIResource) {
  309                           documentStyleSheet.removeStyleSheet(s);
  310                       }
  311                   }
  312               }
  313               String cssRule = sun.swing.
  314                   SwingUtilities2.displayPropertiesToCSS(font,
  315                                                          fg);
  316               styleSheet.addRule(cssRule);
  317               documentStyleSheet.addStyleSheet(styleSheet);
  318               documentStyleSheet.addRule("BASE_SIZE " +
  319                                          component.getFont().getSize());
  320               Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
  321               if (! font.equals(style.getAttribute(FONT_ATTRIBUTE_KEY))) {
  322                   style.addAttribute(FONT_ATTRIBUTE_KEY, font);
  323               }
  324           }
  325       }
  326   
  327       private void updateStyle(Font font, Color fg) {
  328           updateFont(font);
  329           updateForeground(fg);
  330       }
  331   
  332       /**
  333        * Update the color in the default style of the document.
  334        *
  335        * @param color the new color to use or null to remove the color attribute
  336        *              from the document's style
  337        */
  338       private void updateForeground(Color color) {
  339           StyledDocument doc = (StyledDocument)getComponent().getDocument();
  340           Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
  341   
  342           if (style == null) {
  343               return;
  344           }
  345   
  346           if (color == null) {
  347               if (style.getAttribute(StyleConstants.Foreground) != null) {
  348                   style.removeAttribute(StyleConstants.Foreground);
  349               }
  350           } else {
  351               if (! color.equals(StyleConstants.getForeground(style))) {
  352                   StyleConstants.setForeground(style, color);
  353               }
  354           }
  355       }
  356   
  357       /**
  358        * Update the font in the default style of the document.
  359        *
  360        * @param font the new font to use or null to remove the font attribute
  361        *             from the document's style
  362        */
  363       private void updateFont(Font font) {
  364           StyledDocument doc = (StyledDocument)getComponent().getDocument();
  365           Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
  366   
  367           if (style == null) {
  368               return;
  369           }
  370   
  371           String fontFamily = (String) style.getAttribute(StyleConstants.FontFamily);
  372           Integer fontSize = (Integer) style.getAttribute(StyleConstants.FontSize);
  373           Boolean isBold = (Boolean) style.getAttribute(StyleConstants.Bold);
  374           Boolean isItalic = (Boolean) style.getAttribute(StyleConstants.Italic);
  375           Font  fontAttribute = (Font) style.getAttribute(FONT_ATTRIBUTE_KEY);
  376           if (font == null) {
  377               if (fontFamily != null) {
  378                   style.removeAttribute(StyleConstants.FontFamily);
  379               }
  380               if (fontSize != null) {
  381                   style.removeAttribute(StyleConstants.FontSize);
  382               }
  383               if (isBold != null) {
  384                   style.removeAttribute(StyleConstants.Bold);
  385               }
  386               if (isItalic != null) {
  387                   style.removeAttribute(StyleConstants.Italic);
  388               }
  389               if (fontAttribute != null) {
  390                   style.removeAttribute(FONT_ATTRIBUTE_KEY);
  391              }
  392           } else {
  393               if (! font.getName().equals(fontFamily)) {
  394                   StyleConstants.setFontFamily(style, font.getName());
  395               }
  396               if (fontSize == null
  397                     || fontSize.intValue() != font.getSize()) {
  398                   StyleConstants.setFontSize(style, font.getSize());
  399               }
  400               if (isBold == null
  401                     || isBold.booleanValue() != font.isBold()) {
  402                   StyleConstants.setBold(style, font.isBold());
  403               }
  404               if (isItalic == null
  405                     || isItalic.booleanValue() != font.isItalic()) {
  406                   StyleConstants.setItalic(style, font.isItalic());
  407               }
  408               if (! font.equals(fontAttribute)) {
  409                   style.addAttribute(FONT_ATTRIBUTE_KEY, font);
  410               }
  411           }
  412       }
  413   }

Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]