0N/A/*
2362N/A * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage javax.swing.plaf.basic;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.beans.*;
0N/Aimport java.net.URL;
0N/Aimport java.net.MalformedURLException;
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.text.*;
0N/Aimport javax.swing.text.html.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport javax.swing.border.*;
0N/A
0N/A
0N/A/**
0N/A * Provides the look and feel for a JEditorPane.
0N/A * <p>
0N/A * <strong>Warning:</strong>
0N/A * Serialized objects of this class will not be compatible with
0N/A * future Swing releases. The current serialization support is
0N/A * appropriate for short term storage or RMI between applications running
0N/A * the same version of Swing. As of 1.4, support for long term storage
0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup>
0N/A * has been added to the <code>java.beans</code> package.
0N/A * Please see {@link java.beans.XMLEncoder}.
0N/A *
0N/A * @author Timothy Prinzing
0N/A */
0N/Apublic class BasicEditorPaneUI extends BasicTextUI {
0N/A
0N/A /**
0N/A * Creates a UI for the JTextPane.
0N/A *
0N/A * @param c the JTextPane component
0N/A * @return the UI
0N/A */
0N/A public static ComponentUI createUI(JComponent c) {
0N/A return new BasicEditorPaneUI();
0N/A }
0N/A
0N/A /**
0N/A * Creates a new BasicEditorPaneUI.
0N/A */
0N/A public BasicEditorPaneUI() {
0N/A super();
0N/A }
0N/A
0N/A /**
0N/A * Fetches the name used as a key to lookup properties through the
0N/A * UIManager. This is used as a prefix to all the standard
0N/A * text properties.
0N/A *
0N/A * @return the name ("EditorPane")
0N/A */
0N/A protected String getPropertyPrefix() {
0N/A return "EditorPane";
0N/A }
0N/A
0N/A /**
0N/A *{@inheritDoc}
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public void installUI(JComponent c) {
0N/A super.installUI(c);
0N/A updateDisplayProperties(c.getFont(),
0N/A c.getForeground());
0N/A }
0N/A
0N/A /**
0N/A *{@inheritDoc}
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public void uninstallUI(JComponent c) {
0N/A cleanDisplayProperties();
0N/A super.uninstallUI(c);
0N/A }
0N/A
0N/A /**
0N/A * Fetches the EditorKit for the UI. This is whatever is
0N/A * currently set in the associated JEditorPane.
0N/A *
0N/A * @return the editor capabilities
0N/A * @see TextUI#getEditorKit
0N/A */
0N/A public EditorKit getEditorKit(JTextComponent tc) {
0N/A JEditorPane pane = (JEditorPane) getComponent();
0N/A return pane.getEditorKit();
0N/A }
0N/A
0N/A /**
0N/A * Fetch an action map to use. The map for a JEditorPane
0N/A * is not shared because it changes with the EditorKit.
0N/A */
0N/A ActionMap getActionMap() {
0N/A ActionMap am = new ActionMapUIResource();
0N/A am.put("requestFocus", new FocusAction());
0N/A EditorKit editorKit = getEditorKit(getComponent());
0N/A if (editorKit != null) {
0N/A Action[] actions = editorKit.getActions();
0N/A if (actions != null) {
0N/A addActions(am, actions);
0N/A }
0N/A }
0N/A am.put(TransferHandler.getCutAction().getValue(Action.NAME),
0N/A TransferHandler.getCutAction());
0N/A am.put(TransferHandler.getCopyAction().getValue(Action.NAME),
0N/A TransferHandler.getCopyAction());
0N/A am.put(TransferHandler.getPasteAction().getValue(Action.NAME),
0N/A TransferHandler.getPasteAction());
0N/A return am;
0N/A }
0N/A
0N/A /**
0N/A * This method gets called when a bound property is changed
0N/A * on the associated JTextComponent. This is a hook
0N/A * which UI implementations may change to reflect how the
0N/A * UI displays bound properties of JTextComponent subclasses.
0N/A * This is implemented to rebuild the ActionMap based upon an
0N/A * EditorKit change.
0N/A *
0N/A * @param evt the property change event
0N/A */
0N/A protected void propertyChange(PropertyChangeEvent evt) {
0N/A super.propertyChange(evt);
0N/A String name = evt.getPropertyName();
0N/A if ("editorKit".equals(name)) {
0N/A ActionMap map = SwingUtilities.getUIActionMap(getComponent());
0N/A if (map != null) {
0N/A Object oldValue = evt.getOldValue();
0N/A if (oldValue instanceof EditorKit) {
0N/A Action[] actions = ((EditorKit)oldValue).getActions();
0N/A if (actions != null) {
0N/A removeActions(map, actions);
0N/A }
0N/A }
0N/A Object newValue = evt.getNewValue();
0N/A if (newValue instanceof EditorKit) {
0N/A Action[] actions = ((EditorKit)newValue).getActions();
0N/A if (actions != null) {
0N/A addActions(map, actions);
0N/A }
0N/A }
0N/A }
0N/A updateFocusTraversalKeys();
0N/A } else if ("editable".equals(name)) {
0N/A updateFocusTraversalKeys();
0N/A } else if ("foreground".equals(name)
0N/A || "font".equals(name)
0N/A || "document".equals(name)
0N/A || JEditorPane.W3C_LENGTH_UNITS.equals(name)
0N/A || JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name)
0N/A ) {
0N/A JComponent c = getComponent();
0N/A updateDisplayProperties(c.getFont(), c.getForeground());
0N/A if ( JEditorPane.W3C_LENGTH_UNITS.equals(name)
0N/A || JEditorPane.HONOR_DISPLAY_PROPERTIES.equals(name) ) {
0N/A modelChanged();
0N/A }
0N/A if ("foreground".equals(name)) {
0N/A Object honorDisplayPropertiesObject = c.
0N/A getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
0N/A boolean honorDisplayProperties = false;
0N/A if (honorDisplayPropertiesObject instanceof Boolean) {
0N/A honorDisplayProperties =
0N/A ((Boolean)honorDisplayPropertiesObject).booleanValue();
0N/A }
0N/A if (honorDisplayProperties) {
0N/A modelChanged();
0N/A }
0N/A }
0N/A
0N/A
0N/A }
0N/A }
0N/A
0N/A void removeActions(ActionMap map, Action[] actions) {
0N/A int n = actions.length;
0N/A for (int i = 0; i < n; i++) {
0N/A Action a = actions[i];
0N/A map.remove(a.getValue(Action.NAME));
0N/A }
0N/A }
0N/A
0N/A void addActions(ActionMap map, Action[] actions) {
0N/A int n = actions.length;
0N/A for (int i = 0; i < n; i++) {
0N/A Action a = actions[i];
0N/A map.put(a.getValue(Action.NAME), a);
0N/A }
0N/A }
0N/A
0N/A void updateDisplayProperties(Font font, Color fg) {
0N/A JComponent c = getComponent();
0N/A Object honorDisplayPropertiesObject = c.
0N/A getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
0N/A boolean honorDisplayProperties = false;
0N/A Object w3cLengthUnitsObject = c.getClientProperty(JEditorPane.
0N/A W3C_LENGTH_UNITS);
0N/A boolean w3cLengthUnits = false;
0N/A if (honorDisplayPropertiesObject instanceof Boolean) {
0N/A honorDisplayProperties =
0N/A ((Boolean)honorDisplayPropertiesObject).booleanValue();
0N/A }
0N/A if (w3cLengthUnitsObject instanceof Boolean) {
0N/A w3cLengthUnits = ((Boolean)w3cLengthUnitsObject).booleanValue();
0N/A }
0N/A if (this instanceof BasicTextPaneUI
0N/A || honorDisplayProperties) {
0N/A //using equals because can not use UIResource for Boolean
0N/A Document doc = getComponent().getDocument();
0N/A if (doc instanceof StyledDocument) {
0N/A if (doc instanceof HTMLDocument
0N/A && honorDisplayProperties) {
0N/A updateCSS(font, fg);
0N/A } else {
0N/A updateStyle(font, fg);
0N/A }
0N/A }
0N/A } else {
0N/A cleanDisplayProperties();
0N/A }
0N/A if ( w3cLengthUnits ) {
0N/A Document doc = getComponent().getDocument();
0N/A if (doc instanceof HTMLDocument) {
0N/A StyleSheet documentStyleSheet =
0N/A ((HTMLDocument)doc).getStyleSheet();
0N/A documentStyleSheet.addRule("W3C_LENGTH_UNITS_ENABLE");
0N/A }
0N/A } else {
0N/A Document doc = getComponent().getDocument();
0N/A if (doc instanceof HTMLDocument) {
0N/A StyleSheet documentStyleSheet =
0N/A ((HTMLDocument)doc).getStyleSheet();
0N/A documentStyleSheet.addRule("W3C_LENGTH_UNITS_DISABLE");
0N/A }
0N/A
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Attribute key to reference the default font.
0N/A * used in javax.swing.text.StyleContext.getFont
0N/A * to resolve the default font.
0N/A */
0N/A private static final String FONT_ATTRIBUTE_KEY = "FONT_ATTRIBUTE_KEY";
0N/A
0N/A void cleanDisplayProperties() {
0N/A Document document = getComponent().getDocument();
0N/A if (document instanceof HTMLDocument) {
0N/A StyleSheet documentStyleSheet =
0N/A ((HTMLDocument)document).getStyleSheet();
0N/A StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
0N/A if (styleSheets != null) {
0N/A for (StyleSheet s : styleSheets) {
0N/A if (s instanceof StyleSheetUIResource) {
0N/A documentStyleSheet.removeStyleSheet(s);
0N/A documentStyleSheet.addRule("BASE_SIZE_DISABLE");
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
0N/A if (style.getAttribute(FONT_ATTRIBUTE_KEY) != null) {
0N/A style.removeAttribute(FONT_ATTRIBUTE_KEY);
0N/A }
0N/A }
0N/A }
0N/A
0N/A static class StyleSheetUIResource extends StyleSheet implements UIResource {
0N/A }
0N/A
0N/A private void updateCSS(Font font, Color fg) {
0N/A JTextComponent component = getComponent();
0N/A Document document = component.getDocument();
0N/A if (document instanceof HTMLDocument) {
0N/A StyleSheet styleSheet = new StyleSheetUIResource();
0N/A StyleSheet documentStyleSheet =
0N/A ((HTMLDocument)document).getStyleSheet();
0N/A StyleSheet[] styleSheets = documentStyleSheet.getStyleSheets();
0N/A if (styleSheets != null) {
0N/A for (StyleSheet s : styleSheets) {
0N/A if (s instanceof StyleSheetUIResource) {
0N/A documentStyleSheet.removeStyleSheet(s);
0N/A }
0N/A }
0N/A }
0N/A String cssRule = sun.swing.
0N/A SwingUtilities2.displayPropertiesToCSS(font,
0N/A fg);
0N/A styleSheet.addRule(cssRule);
0N/A documentStyleSheet.addStyleSheet(styleSheet);
0N/A documentStyleSheet.addRule("BASE_SIZE " +
0N/A component.getFont().getSize());
0N/A Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE);
0N/A if (! font.equals(style.getAttribute(FONT_ATTRIBUTE_KEY))) {
0N/A style.addAttribute(FONT_ATTRIBUTE_KEY, font);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private void updateStyle(Font font, Color fg) {
0N/A updateFont(font);
0N/A updateForeground(fg);
0N/A }
0N/A
0N/A /**
0N/A * Update the color in the default style of the document.
0N/A *
0N/A * @param color the new color to use or null to remove the color attribute
0N/A * from the document's style
0N/A */
0N/A private void updateForeground(Color color) {
0N/A StyledDocument doc = (StyledDocument)getComponent().getDocument();
0N/A Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
0N/A
0N/A if (style == null) {
0N/A return;
0N/A }
0N/A
0N/A if (color == null) {
0N/A if (style.getAttribute(StyleConstants.Foreground) != null) {
0N/A style.removeAttribute(StyleConstants.Foreground);
0N/A }
0N/A } else {
0N/A if (! color.equals(StyleConstants.getForeground(style))) {
0N/A StyleConstants.setForeground(style, color);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Update the font in the default style of the document.
0N/A *
0N/A * @param font the new font to use or null to remove the font attribute
0N/A * from the document's style
0N/A */
0N/A private void updateFont(Font font) {
0N/A StyledDocument doc = (StyledDocument)getComponent().getDocument();
0N/A Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
0N/A
0N/A if (style == null) {
0N/A return;
0N/A }
0N/A
0N/A String fontFamily = (String) style.getAttribute(StyleConstants.FontFamily);
0N/A Integer fontSize = (Integer) style.getAttribute(StyleConstants.FontSize);
0N/A Boolean isBold = (Boolean) style.getAttribute(StyleConstants.Bold);
0N/A Boolean isItalic = (Boolean) style.getAttribute(StyleConstants.Italic);
0N/A Font fontAttribute = (Font) style.getAttribute(FONT_ATTRIBUTE_KEY);
0N/A if (font == null) {
0N/A if (fontFamily != null) {
0N/A style.removeAttribute(StyleConstants.FontFamily);
0N/A }
0N/A if (fontSize != null) {
0N/A style.removeAttribute(StyleConstants.FontSize);
0N/A }
0N/A if (isBold != null) {
0N/A style.removeAttribute(StyleConstants.Bold);
0N/A }
0N/A if (isItalic != null) {
0N/A style.removeAttribute(StyleConstants.Italic);
0N/A }
0N/A if (fontAttribute != null) {
0N/A style.removeAttribute(FONT_ATTRIBUTE_KEY);
0N/A }
0N/A } else {
0N/A if (! font.getName().equals(fontFamily)) {
0N/A StyleConstants.setFontFamily(style, font.getName());
0N/A }
0N/A if (fontSize == null
0N/A || fontSize.intValue() != font.getSize()) {
0N/A StyleConstants.setFontSize(style, font.getSize());
0N/A }
0N/A if (isBold == null
0N/A || isBold.booleanValue() != font.isBold()) {
0N/A StyleConstants.setBold(style, font.isBold());
0N/A }
0N/A if (isItalic == null
0N/A || isItalic.booleanValue() != font.isItalic()) {
0N/A StyleConstants.setItalic(style, font.isItalic());
0N/A }
0N/A if (! font.equals(fontAttribute)) {
0N/A style.addAttribute(FONT_ATTRIBUTE_KEY, font);
0N/A }
0N/A }
0N/A }
0N/A}