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