1 /*
   2  * Copyright (c) 1997, 2017, 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.tree;
  27 
  28 import java.awt.Color;
  29 import java.awt.Component;
  30 import java.awt.Dimension;
  31 import java.awt.Font;
  32 import java.awt.Graphics;
  33 import java.awt.Insets;
  34 import java.awt.Rectangle;
  35 import javax.swing.plaf.ColorUIResource;
  36 import javax.swing.plaf.FontUIResource;
  37 import javax.swing.plaf.UIResource;
  38 import javax.swing.plaf.basic.BasicGraphicsUtils;
  39 import javax.swing.Icon;
  40 import javax.swing.JLabel;
  41 import javax.swing.JTree;
  42 import javax.swing.LookAndFeel;
  43 import javax.swing.UIManager;
  44 import javax.swing.border.EmptyBorder;
  45 import sun.swing.DefaultLookup;
  46 
  47 /**
  48  * Displays an entry in a tree.
  49  * <code>DefaultTreeCellRenderer</code> is not opaque and
  50  * unless you subclass paint you should not change this.
  51  * See <a
  52  href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
  53  * in <em>The Java Tutorial</em>
  54  * for examples of customizing node display using this class.
  55  * <p>
  56  * The set of icons and colors used by {@code DefaultTreeCellRenderer}
  57  * can be configured using the various setter methods. The value for
  58  * each property is initialized from the defaults table. When the
  59  * look and feel changes ({@code updateUI} is invoked), any properties
  60  * that have a value of type {@code UIResource} are refreshed from the
  61  * defaults table. The following table lists the mapping between
  62  * {@code DefaultTreeCellRenderer} property and defaults table key:
  63  * <table border="1" cellpadding="1" cellspacing="0" summary="">
  64  *   <tr valign="top" style="text-align:left">
  65  *     <th style="background-color:#CCCCFF;text-align:left">Property:
  66  *     <th style="background-color:#CCCCFF;text-align:left">Key:
  67  *   <tr><td>"leafIcon"<td>"Tree.leafIcon"
  68  *   <tr><td>"closedIcon"<td>"Tree.closedIcon"
  69  *   <tr><td>"openIcon"<td>"Tree.openIcon"
  70  *   <tr><td>"textSelectionColor"<td>"Tree.selectionForeground"
  71  *   <tr><td>"textNonSelectionColor"<td>"Tree.textForeground"
  72  *   <tr><td>"backgroundSelectionColor"<td>"Tree.selectionBackground"
  73  *   <tr><td>"backgroundNonSelectionColor"<td>"Tree.textBackground"
  74  *   <tr><td>"borderSelectionColor"<td>"Tree.selectionBorderColor"
  75  * </table>
  76  * <p>
  77  * <strong><a id="override">Implementation Note:</a></strong>
  78  * This class overrides
  79  * <code>invalidate</code>,
  80  * <code>validate</code>,
  81  * <code>revalidate</code>,
  82  * <code>repaint</code>,
  83  * and
  84  * <code>firePropertyChange</code>
  85  * solely to improve performance.
  86  * If not overridden, these frequently called methods would execute code paths
  87  * that are unnecessary for the default tree cell renderer.
  88  * If you write your own renderer,
  89  * take care to weigh the benefits and
  90  * drawbacks of overriding these methods.
  91  *
  92  * <p>
  93  * <strong>Warning:</strong>
  94  * Serialized objects of this class will not be compatible with
  95  * future Swing releases. The current serialization support is
  96  * appropriate for short term storage or RMI between applications running
  97  * the same version of Swing.  As of 1.4, support for long term storage
  98  * of all JavaBeans&trade;
  99  * has been added to the <code>java.beans</code> package.
 100  * Please see {@link java.beans.XMLEncoder}.
 101  *
 102  * @author Rob Davis
 103  * @author Ray Ryan
 104  * @author Scott Violet
 105  */
 106 @SuppressWarnings("serial") // Same-version serialization only
 107 public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
 108 {
 109     /** Last tree the renderer was painted in. */
 110     private JTree tree;
 111 
 112     /** Is the value currently selected. */
 113     protected boolean selected;
 114     /** True if has focus. */
 115     protected boolean hasFocus;
 116     /** True if draws focus border around icon as well. */
 117     private boolean drawsFocusBorderAroundIcon;
 118     /** If true, a dashed line is drawn as the focus indicator. */
 119     private boolean drawDashedFocusIndicator;
 120 
 121     // If drawDashedFocusIndicator is true, the following are used.
 122     /**
 123      * Background color of the tree.
 124      */
 125     private Color treeBGColor;
 126     /**
 127      * Color to draw the focus indicator in, determined from the background.
 128      * color.
 129      */
 130     private Color focusBGColor;
 131 
 132     // Icons
 133     /** Icon used to show non-leaf nodes that aren't expanded. */
 134     protected transient Icon closedIcon;
 135 
 136     /** Icon used to show leaf nodes. */
 137     protected transient Icon leafIcon;
 138 
 139     /** Icon used to show non-leaf nodes that are expanded. */
 140     protected transient Icon openIcon;
 141 
 142     // Colors
 143     /** Color to use for the foreground for selected nodes. */
 144     protected Color textSelectionColor;
 145 
 146     /** Color to use for the foreground for non-selected nodes. */
 147     protected Color textNonSelectionColor;
 148 
 149     /** Color to use for the background when a node is selected. */
 150     protected Color backgroundSelectionColor;
 151 
 152     /** Color to use for the background when the node isn't selected. */
 153     protected Color backgroundNonSelectionColor;
 154 
 155     /** Color to use for the focus indicator when the node has focus. */
 156     protected Color borderSelectionColor;
 157 
 158     private boolean isDropCell;
 159     private boolean fillBackground;
 160 
 161     /**
 162      * Set to true after the constructor has run.
 163      */
 164     private boolean inited;
 165 
 166     /**
 167      * Creates a {@code DefaultTreeCellRenderer}. Icons and text color are
 168      * determined from the {@code UIManager}.
 169      */
 170     public DefaultTreeCellRenderer() {
 171         inited = true;
 172     }
 173 
 174     /**
 175      * {@inheritDoc}
 176      *
 177      * @since 1.7
 178      */
 179     public void updateUI() {
 180         super.updateUI();
 181         // To avoid invoking new methods from the constructor, the
 182         // inited field is first checked. If inited is false, the constructor
 183         // has not run and there is no point in checking the value. As
 184         // all look and feels have a non-null value for these properties,
 185         // a null value means the developer has specifically set it to
 186         // null. As such, if the value is null, this does not reset the
 187         // value.
 188         if (!inited || (getLeafIcon() instanceof UIResource)) {
 189             setLeafIcon(DefaultLookup.getIcon(this, ui, "Tree.leafIcon"));
 190         }
 191         if (!inited || (getClosedIcon() instanceof UIResource)) {
 192             setClosedIcon(DefaultLookup.getIcon(this, ui, "Tree.closedIcon"));
 193         }
 194         if (!inited || (getOpenIcon() instanceof UIResource)) {
 195             setOpenIcon(DefaultLookup.getIcon(this, ui, "Tree.openIcon"));
 196         }
 197         if (!inited || (getTextSelectionColor() instanceof UIResource)) {
 198             setTextSelectionColor(
 199                     DefaultLookup.getColor(this, ui, "Tree.selectionForeground"));
 200         }
 201         if (!inited || (getTextNonSelectionColor() instanceof UIResource)) {
 202             setTextNonSelectionColor(
 203                     DefaultLookup.getColor(this, ui, "Tree.textForeground"));
 204         }
 205         if (!inited || (getBackgroundSelectionColor() instanceof UIResource)) {
 206             setBackgroundSelectionColor(
 207                     DefaultLookup.getColor(this, ui, "Tree.selectionBackground"));
 208         }
 209         if (!inited ||
 210                 (getBackgroundNonSelectionColor() instanceof UIResource)) {
 211             setBackgroundNonSelectionColor(
 212                     DefaultLookup.getColor(this, ui, "Tree.textBackground"));
 213         }
 214         if (!inited || (getBorderSelectionColor() instanceof UIResource)) {
 215             setBorderSelectionColor(
 216                     DefaultLookup.getColor(this, ui, "Tree.selectionBorderColor"));
 217         }
 218         drawsFocusBorderAroundIcon = DefaultLookup.getBoolean(
 219                 this, ui, "Tree.drawsFocusBorderAroundIcon", false);
 220         drawDashedFocusIndicator = DefaultLookup.getBoolean(
 221                 this, ui, "Tree.drawDashedFocusIndicator", false);
 222 
 223         fillBackground = DefaultLookup.getBoolean(this, ui, "Tree.rendererFillBackground", true);
 224         Insets margins = DefaultLookup.getInsets(this, ui, "Tree.rendererMargins");
 225         if (margins != null) {
 226             setBorder(new EmptyBorder(margins.top, margins.left,
 227                     margins.bottom, margins.right));
 228         }
 229 
 230         setName("Tree.cellRenderer");
 231     }
 232 
 233 
 234     /**
 235       * Returns the default icon, for the current laf, that is used to
 236       * represent non-leaf nodes that are expanded.
 237       *
 238       * @return the default icon, for the current laf, that is used to
 239       *         represent non-leaf nodes that are expanded.
 240       */
 241     public Icon getDefaultOpenIcon() {
 242         return DefaultLookup.getIcon(this, ui, "Tree.openIcon");
 243     }
 244 
 245     /**
 246       * Returns the default icon, for the current laf, that is used to
 247       * represent non-leaf nodes that are not expanded.
 248       *
 249       * @return the default icon, for the current laf, that is used to
 250       *         represent non-leaf nodes that are not expanded.
 251       */
 252     public Icon getDefaultClosedIcon() {
 253         return DefaultLookup.getIcon(this, ui, "Tree.closedIcon");
 254     }
 255 
 256     /**
 257       * Returns the default icon, for the current laf, that is used to
 258       * represent leaf nodes.
 259       *
 260       * @return the default icon, for the current laf, that is used to
 261       *         represent leaf nodes.
 262       */
 263     public Icon getDefaultLeafIcon() {
 264         return DefaultLookup.getIcon(this, ui, "Tree.leafIcon");
 265     }
 266 
 267     /**
 268       * Sets the icon used to represent non-leaf nodes that are expanded.
 269       *
 270       * @param newIcon the icon to be used for expanded non-leaf nodes
 271       */
 272     public void setOpenIcon(Icon newIcon) {
 273         openIcon = newIcon;
 274     }
 275 
 276     /**
 277       * Returns the icon used to represent non-leaf nodes that are expanded.
 278       *
 279       * @return the icon used to represent non-leaf nodes that are expanded
 280       */
 281     public Icon getOpenIcon() {
 282         return openIcon;
 283     }
 284 
 285     /**
 286       * Sets the icon used to represent non-leaf nodes that are not expanded.
 287       *
 288       * @param newIcon the icon to be used for not expanded non-leaf nodes
 289       */
 290     public void setClosedIcon(Icon newIcon) {
 291         closedIcon = newIcon;
 292     }
 293 
 294     /**
 295       * Returns the icon used to represent non-leaf nodes that are not
 296       * expanded.
 297       *
 298       * @return the icon used to represent non-leaf nodes that are not
 299       *         expanded
 300       */
 301     public Icon getClosedIcon() {
 302         return closedIcon;
 303     }
 304 
 305     /**
 306       * Sets the icon used to represent leaf nodes.
 307       *
 308       * @param newIcon icon to be used for leaf nodes
 309       */
 310     public void setLeafIcon(Icon newIcon) {
 311         leafIcon = newIcon;
 312     }
 313 
 314     /**
 315       * Returns the icon used to represent leaf nodes.
 316       *
 317       * @return the icon used to represent leaf nodes
 318       */
 319     public Icon getLeafIcon() {
 320         return leafIcon;
 321     }
 322 
 323     /**
 324       * Sets the color the text is drawn with when the node is selected.
 325       *
 326       * @param newColor color to be used for text when the node is selected
 327       */
 328     public void setTextSelectionColor(Color newColor) {
 329         textSelectionColor = newColor;
 330     }
 331 
 332     /**
 333       * Returns the color the text is drawn with when the node is selected.
 334       *
 335       * @return the color the text is drawn with when the node is selected
 336       */
 337     public Color getTextSelectionColor() {
 338         return textSelectionColor;
 339     }
 340 
 341     /**
 342       * Sets the color the text is drawn with when the node isn't selected.
 343       *
 344       * @param newColor color to be used for text when the node isn't selected
 345       */
 346     public void setTextNonSelectionColor(Color newColor) {
 347         textNonSelectionColor = newColor;
 348     }
 349 
 350     /**
 351       * Returns the color the text is drawn with when the node isn't selected.
 352       *
 353       * @return the color the text is drawn with when the node isn't selected.
 354       */
 355     public Color getTextNonSelectionColor() {
 356         return textNonSelectionColor;
 357     }
 358 
 359     /**
 360       * Sets the color to use for the background if node is selected.
 361       *
 362       * @param newColor to be used for the background if the node is selected
 363       */
 364     public void setBackgroundSelectionColor(Color newColor) {
 365         backgroundSelectionColor = newColor;
 366     }
 367 
 368 
 369     /**
 370       * Returns the color to use for the background if node is selected.
 371       *
 372       * @return the color to use for the background if node is selected
 373       */
 374     public Color getBackgroundSelectionColor() {
 375         return backgroundSelectionColor;
 376     }
 377 
 378     /**
 379       * Sets the background color to be used for non selected nodes.
 380       *
 381       * @param newColor color to be used for the background for non selected nodes
 382       */
 383     public void setBackgroundNonSelectionColor(Color newColor) {
 384         backgroundNonSelectionColor = newColor;
 385     }
 386 
 387     /**
 388       * Returns the background color to be used for non selected nodes.
 389       *
 390       * @return the background color to be used for non selected nodes.
 391       */
 392     public Color getBackgroundNonSelectionColor() {
 393         return backgroundNonSelectionColor;
 394     }
 395 
 396     /**
 397       * Sets the color to use for the border.
 398       *
 399       * @param newColor color to be used for the border
 400       */
 401     public void setBorderSelectionColor(Color newColor) {
 402         borderSelectionColor = newColor;
 403     }
 404 
 405     /**
 406       * Returns the color the border is drawn.
 407       *
 408       * @return the color the border is drawn
 409       */
 410     public Color getBorderSelectionColor() {
 411         return borderSelectionColor;
 412     }
 413 
 414     /**
 415      * Subclassed to map <code>FontUIResource</code>s to null. If
 416      * <code>font</code> is null, or a <code>FontUIResource</code>, this
 417      * has the effect of letting the font of the JTree show
 418      * through. On the other hand, if <code>font</code> is non-null, and not
 419      * a <code>FontUIResource</code>, the font becomes <code>font</code>.
 420      */
 421     public void setFont(Font font) {
 422         if(font instanceof FontUIResource)
 423             font = null;
 424         super.setFont(font);
 425     }
 426 
 427     /**
 428      * Gets the font of this component.
 429      * @return this component's font; if a font has not been set
 430      * for this component, the font of its parent is returned
 431      */
 432     public Font getFont() {
 433         Font font = super.getFont();
 434 
 435         if (font == null && tree != null) {
 436             // Strive to return a non-null value, otherwise the html support
 437             // will typically pick up the wrong font in certain situations.
 438             font = tree.getFont();
 439         }
 440         return font;
 441     }
 442 
 443     /**
 444      * Subclassed to map <code>ColorUIResource</code>s to null. If
 445      * <code>color</code> is null, or a <code>ColorUIResource</code>, this
 446      * has the effect of letting the background color of the JTree show
 447      * through. On the other hand, if <code>color</code> is non-null, and not
 448      * a <code>ColorUIResource</code>, the background becomes
 449      * <code>color</code>.
 450      */
 451     public void setBackground(Color color) {
 452         if(color instanceof ColorUIResource)
 453             color = null;
 454         super.setBackground(color);
 455     }
 456 
 457     /**
 458       * Configures the renderer based on the passed in components.
 459       * The value is set from messaging the tree with
 460       * <code>convertValueToText</code>, which ultimately invokes
 461       * <code>toString</code> on <code>value</code>.
 462       * The foreground color is set based on the selection and the icon
 463       * is set based on the <code>leaf</code> and <code>expanded</code>
 464       * parameters.
 465       */
 466     public Component getTreeCellRendererComponent(JTree tree, Object value,
 467                                                   boolean sel,
 468                                                   boolean expanded,
 469                                                   boolean leaf, int row,
 470                                                   boolean hasFocus) {
 471         String         stringValue = tree.convertValueToText(value, sel,
 472                                           expanded, leaf, row, hasFocus);
 473 
 474         this.tree = tree;
 475         this.hasFocus = hasFocus;
 476         setText(stringValue);
 477 
 478         Color fg = null;
 479         isDropCell = false;
 480 
 481         JTree.DropLocation dropLocation = tree.getDropLocation();
 482         if (dropLocation != null
 483                 && dropLocation.getChildIndex() == -1
 484                 && tree.getRowForPath(dropLocation.getPath()) == row) {
 485 
 486             Color col = DefaultLookup.getColor(this, ui, "Tree.dropCellForeground");
 487             if (col != null) {
 488                 fg = col;
 489             } else {
 490                 fg = getTextSelectionColor();
 491             }
 492 
 493             isDropCell = true;
 494         } else if (sel) {
 495             fg = getTextSelectionColor();
 496         } else {
 497             fg = getTextNonSelectionColor();
 498         }
 499 
 500         setForeground(fg);
 501 
 502         Icon icon = null;
 503         if (leaf) {
 504             icon = getLeafIcon();
 505         } else if (expanded) {
 506             icon = getOpenIcon();
 507         } else {
 508             icon = getClosedIcon();
 509         }
 510 
 511         if (!tree.isEnabled()) {
 512             setEnabled(false);
 513             LookAndFeel laf = UIManager.getLookAndFeel();
 514             Icon disabledIcon = laf.getDisabledIcon(tree, icon);
 515             if (disabledIcon != null) icon = disabledIcon;
 516             setDisabledIcon(icon);
 517         } else {
 518             setEnabled(true);
 519             setIcon(icon);
 520         }
 521         setComponentOrientation(tree.getComponentOrientation());
 522 
 523         selected = sel;
 524 
 525         return this;
 526     }
 527 
 528     /**
 529       * Paints the value.  The background is filled based on selected.
 530       */
 531     public void paint(Graphics g) {
 532         Color bColor;
 533 
 534         if (isDropCell) {
 535             bColor = DefaultLookup.getColor(this, ui, "Tree.dropCellBackground");
 536             if (bColor == null) {
 537                 bColor = getBackgroundSelectionColor();
 538             }
 539         } else if (selected) {
 540             bColor = getBackgroundSelectionColor();
 541         } else {
 542             bColor = getBackgroundNonSelectionColor();
 543             if (bColor == null) {
 544                 bColor = getBackground();
 545             }
 546         }
 547 
 548         int imageOffset = -1;
 549         if (bColor != null && fillBackground) {
 550             imageOffset = getLabelStart();
 551             g.setColor(bColor);
 552             if(getComponentOrientation().isLeftToRight()) {
 553                 g.fillRect(imageOffset, 0, getWidth() - imageOffset,
 554                            getHeight());
 555             } else {
 556                 g.fillRect(0, 0, getWidth() - imageOffset,
 557                            getHeight());
 558             }
 559         }
 560 
 561         if (hasFocus) {
 562             if (drawsFocusBorderAroundIcon) {
 563                 imageOffset = 0;
 564             }
 565             else if (imageOffset == -1) {
 566                 imageOffset = getLabelStart();
 567             }
 568             if(getComponentOrientation().isLeftToRight()) {
 569                 paintFocus(g, imageOffset, 0, getWidth() - imageOffset,
 570                            getHeight(), bColor);
 571             } else {
 572                 paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight(), bColor);
 573             }
 574         }
 575         super.paint(g);
 576     }
 577 
 578     private void paintFocus(Graphics g, int x, int y, int w, int h, Color notColor) {
 579         Color       bsColor = getBorderSelectionColor();
 580 
 581         if (bsColor != null && (selected || !drawDashedFocusIndicator)) {
 582             g.setColor(bsColor);
 583             g.drawRect(x, y, w - 1, h - 1);
 584         }
 585         if (drawDashedFocusIndicator && notColor != null) {
 586             if (treeBGColor != notColor) {
 587                 treeBGColor = notColor;
 588                 focusBGColor = new Color(~notColor.getRGB());
 589             }
 590             g.setColor(focusBGColor);
 591             BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
 592         }
 593     }
 594 
 595     private int getLabelStart() {
 596         Icon currentI = getIcon();
 597         if(currentI != null && getText() != null) {
 598             return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
 599         }
 600         return 0;
 601     }
 602 
 603     /**
 604      * Overrides <code>JComponent.getPreferredSize</code> to
 605      * return slightly wider preferred size value.
 606      */
 607     public Dimension getPreferredSize() {
 608         Dimension        retDimension = super.getPreferredSize();
 609 
 610         if(retDimension != null)
 611             retDimension = new Dimension(retDimension.width + 3,
 612                                          retDimension.height);
 613         return retDimension;
 614     }
 615 
 616    /**
 617     * Overridden for performance reasons.
 618     * See the <a href="#override">Implementation Note</a>
 619     * for more information.
 620     */
 621     public void validate() {}
 622 
 623    /**
 624     * Overridden for performance reasons.
 625     * See the <a href="#override">Implementation Note</a>
 626     * for more information.
 627     *
 628     * @since 1.5
 629     */
 630     public void invalidate() {}
 631 
 632    /**
 633     * Overridden for performance reasons.
 634     * See the <a href="#override">Implementation Note</a>
 635     * for more information.
 636     */
 637     public void revalidate() {}
 638 
 639    /**
 640     * Overridden for performance reasons.
 641     * See the <a href="#override">Implementation Note</a>
 642     * for more information.
 643     */
 644     public void repaint(long tm, int x, int y, int width, int height) {}
 645 
 646    /**
 647     * Overridden for performance reasons.
 648     * See the <a href="#override">Implementation Note</a>
 649     * for more information.
 650     */
 651     public void repaint(Rectangle r) {}
 652 
 653    /**
 654     * Overridden for performance reasons.
 655     * See the <a href="#override">Implementation Note</a>
 656     * for more information.
 657     *
 658     * @since 1.5
 659     */
 660     public void repaint() {}
 661 
 662    /**
 663     * Overridden for performance reasons.
 664     * See the <a href="#override">Implementation Note</a>
 665     * for more information.
 666     */
 667     protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
 668         // Strings get interned...
 669         if (propertyName == "text"
 670                 || ((propertyName == "font" || propertyName == "foreground")
 671                     && oldValue != newValue
 672                     && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
 673 
 674             super.firePropertyChange(propertyName, oldValue, newValue);
 675         }
 676     }
 677 
 678    /**
 679     * Overridden for performance reasons.
 680     * See the <a href="#override">Implementation Note</a>
 681     * for more information.
 682     */
 683     public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}
 684 
 685    /**
 686     * Overridden for performance reasons.
 687     * See the <a href="#override">Implementation Note</a>
 688     * for more information.
 689     */
 690     public void firePropertyChange(String propertyName, char oldValue, char newValue) {}
 691 
 692    /**
 693     * Overridden for performance reasons.
 694     * See the <a href="#override">Implementation Note</a>
 695     * for more information.
 696     */
 697     public void firePropertyChange(String propertyName, short oldValue, short newValue) {}
 698 
 699    /**
 700     * Overridden for performance reasons.
 701     * See the <a href="#override">Implementation Note</a>
 702     * for more information.
 703     */
 704     public void firePropertyChange(String propertyName, int oldValue, int newValue) {}
 705 
 706    /**
 707     * Overridden for performance reasons.
 708     * See the <a href="#override">Implementation Note</a>
 709     * for more information.
 710     */
 711     public void firePropertyChange(String propertyName, long oldValue, long newValue) {}
 712 
 713    /**
 714     * Overridden for performance reasons.
 715     * See the <a href="#override">Implementation Note</a>
 716     * for more information.
 717     */
 718     public void firePropertyChange(String propertyName, float oldValue, float newValue) {}
 719 
 720    /**
 721     * Overridden for performance reasons.
 722     * See the <a href="#override">Implementation Note</a>
 723     * for more information.
 724     */
 725     public void firePropertyChange(String propertyName, double oldValue, double newValue) {}
 726 
 727    /**
 728     * Overridden for performance reasons.
 729     * See the <a href="#override">Implementation Note</a>
 730     * for more information.
 731     */
 732     public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
 733 
 734 }