KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > tree > DefaultTreeCellRenderer


1 /*
2  * @(#)DefaultTreeCellRenderer.java 1.51 04/01/23
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.tree;
9
10 import javax.swing.*;
11 import javax.swing.plaf.ColorUIResource JavaDoc;
12 import javax.swing.plaf.FontUIResource JavaDoc;
13 import javax.swing.plaf.basic.BasicGraphicsUtils JavaDoc;
14 import java.awt.*;
15 import java.awt.event.*;
16 import java.beans.*;
17 import java.io.*;
18 import java.util.*;
19
20 /**
21  * Displays an entry in a tree.
22  * <code>DefaultTreeCellRenderer</code> is not opaque and
23  * unless you subclass paint you should not change this.
24  * See <a
25  href="http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html">How to Use Trees</a>
26  * in <em>The Java Tutorial</em>
27  * for examples of customizing node display using this class.
28  * <p>
29  *
30  * <strong><a name="override">Implementation Note:</a></strong>
31  * This class overrides
32  * <code>invalidate</code>,
33  * <code>validate</code>,
34  * <code>revalidate</code>,
35  * <code>repaint</code>,
36  * and
37  * <code>firePropertyChange</code>
38  * solely to improve performance.
39  * If not overridden, these frequently called methods would execute code paths
40  * that are unnecessary for the default tree cell renderer.
41  * If you write your own renderer,
42  * take care to weigh the benefits and
43  * drawbacks of overriding these methods.
44  *
45  * <p>
46  * <strong>Warning:</strong>
47  * Serialized objects of this class will not be compatible with
48  * future Swing releases. The current serialization support is
49  * appropriate for short term storage or RMI between applications running
50  * the same version of Swing. As of 1.4, support for long term storage
51  * of all JavaBeans<sup><font size="-2">TM</font></sup>
52  * has been added to the <code>java.beans</code> package.
53  * Please see {@link java.beans.XMLEncoder}.
54  *
55  * @version 1.51 01/23/04
56  * @author Rob Davis
57  * @author Ray Ryan
58  * @author Scott Violet
59  */

60 public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer JavaDoc
61 {
62     /** Last tree the renderer was painted in. */
63     private JTree tree;
64
65     /** Is the value currently selected. */
66     protected boolean selected;
67     /** True if has focus. */
68     protected boolean hasFocus;
69     /** True if draws focus border around icon as well. */
70     private boolean drawsFocusBorderAroundIcon;
71     /** If true, a dashed line is drawn as the focus indicator. */
72     private boolean drawDashedFocusIndicator;
73     
74     // If drawDashedFocusIndicator is true, the following are used.
75
/**
76      * Background color of the tree.
77      */

78     private Color treeBGColor;
79     /**
80      * Color to draw the focus indicator in, determined from the background.
81      * color.
82      */

83     private Color focusBGColor;
84
85     // Icons
86
/** Icon used to show non-leaf nodes that aren't expanded. */
87     transient protected Icon closedIcon;
88
89     /** Icon used to show leaf nodes. */
90     transient protected Icon leafIcon;
91
92     /** Icon used to show non-leaf nodes that are expanded. */
93     transient protected Icon openIcon;
94
95     // Colors
96
/** Color to use for the foreground for selected nodes. */
97     protected Color textSelectionColor;
98
99     /** Color to use for the foreground for non-selected nodes. */
100     protected Color textNonSelectionColor;
101
102     /** Color to use for the background when a node is selected. */
103     protected Color backgroundSelectionColor;
104
105     /** Color to use for the background when the node isn't selected. */
106     protected Color backgroundNonSelectionColor;
107
108     /** Color to use for the focus indicator when the node has focus. */
109     protected Color borderSelectionColor;
110
111     /**
112       * Returns a new instance of DefaultTreeCellRenderer. Alignment is
113       * set to left aligned. Icons and text color are determined from the
114       * UIManager.
115       */

116     public DefaultTreeCellRenderer() {
117     setHorizontalAlignment(JLabel.LEFT);
118
119     setLeafIcon(UIManager.getIcon("Tree.leafIcon"));
120     setClosedIcon(UIManager.getIcon("Tree.closedIcon"));
121     setOpenIcon(UIManager.getIcon("Tree.openIcon"));
122
123     setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
124     setTextNonSelectionColor(UIManager.getColor("Tree.textForeground"));
125     setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
126     setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
127     setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
128     Object JavaDoc value = UIManager.get("Tree.drawsFocusBorderAroundIcon");
129     drawsFocusBorderAroundIcon = (value != null && ((Boolean JavaDoc)value).
130                       booleanValue());
131     value = UIManager.get("Tree.drawDashedFocusIndicator");
132     drawDashedFocusIndicator = (value != null && ((Boolean JavaDoc)value).
133                     booleanValue());
134     }
135
136
137     /**
138       * Returns the default icon, for the current laf, that is used to
139       * represent non-leaf nodes that are expanded.
140       */

141     public Icon getDefaultOpenIcon() {
142     return UIManager.getIcon("Tree.openIcon");
143     }
144
145     /**
146       * Returns the default icon, for the current laf, that is used to
147       * represent non-leaf nodes that are not expanded.
148       */

149     public Icon getDefaultClosedIcon() {
150     return UIManager.getIcon("Tree.closedIcon");
151     }
152
153     /**
154       * Returns the default icon, for the current laf, that is used to
155       * represent leaf nodes.
156       */

157     public Icon getDefaultLeafIcon() {
158     return UIManager.getIcon("Tree.leafIcon");
159     }
160
161     /**
162       * Sets the icon used to represent non-leaf nodes that are expanded.
163       */

164     public void setOpenIcon(Icon newIcon) {
165     openIcon = newIcon;
166     }
167
168     /**
169       * Returns the icon used to represent non-leaf nodes that are expanded.
170       */

171     public Icon getOpenIcon() {
172     return openIcon;
173     }
174
175     /**
176       * Sets the icon used to represent non-leaf nodes that are not expanded.
177       */

178     public void setClosedIcon(Icon newIcon) {
179     closedIcon = newIcon;
180     }
181
182     /**
183       * Returns the icon used to represent non-leaf nodes that are not
184       * expanded.
185       */

186     public Icon getClosedIcon() {
187     return closedIcon;
188     }
189
190     /**
191       * Sets the icon used to represent leaf nodes.
192       */

193     public void setLeafIcon(Icon newIcon) {
194     leafIcon = newIcon;
195     }
196
197     /**
198       * Returns the icon used to represent leaf nodes.
199       */

200     public Icon getLeafIcon() {
201     return leafIcon;
202     }
203
204     /**
205       * Sets the color the text is drawn with when the node is selected.
206       */

207     public void setTextSelectionColor(Color newColor) {
208     textSelectionColor = newColor;
209     }
210
211     /**
212       * Returns the color the text is drawn with when the node is selected.
213       */

214     public Color getTextSelectionColor() {
215     return textSelectionColor;
216     }
217
218     /**
219       * Sets the color the text is drawn with when the node isn't selected.
220       */

221     public void setTextNonSelectionColor(Color newColor) {
222     textNonSelectionColor = newColor;
223     }
224
225     /**
226       * Returns the color the text is drawn with when the node isn't selected.
227       */

228     public Color getTextNonSelectionColor() {
229     return textNonSelectionColor;
230     }
231
232     /**
233       * Sets the color to use for the background if node is selected.
234       */

235     public void setBackgroundSelectionColor(Color newColor) {
236     backgroundSelectionColor = newColor;
237     }
238
239
240     /**
241       * Returns the color to use for the background if node is selected.
242       */

243     public Color getBackgroundSelectionColor() {
244     return backgroundSelectionColor;
245     }
246
247     /**
248       * Sets the background color to be used for non selected nodes.
249       */

250     public void setBackgroundNonSelectionColor(Color newColor) {
251     backgroundNonSelectionColor = newColor;
252     }
253
254     /**
255       * Returns the background color to be used for non selected nodes.
256       */

257     public Color getBackgroundNonSelectionColor() {
258     return backgroundNonSelectionColor;
259     }
260
261     /**
262       * Sets the color to use for the border.
263       */

264     public void setBorderSelectionColor(Color newColor) {
265     borderSelectionColor = newColor;
266     }
267
268     /**
269       * Returns the color the border is drawn.
270       */

271     public Color getBorderSelectionColor() {
272     return borderSelectionColor;
273     }
274
275     /**
276      * Subclassed to map <code>FontUIResource</code>s to null. If
277      * <code>font</code> is null, or a <code>FontUIResource</code>, this
278      * has the effect of letting the font of the JTree show
279      * through. On the other hand, if <code>font</code> is non-null, and not
280      * a <code>FontUIResource</code>, the font becomes <code>font</code>.
281      */

282     public void setFont(Font font) {
283     if(font instanceof FontUIResource JavaDoc)
284         font = null;
285     super.setFont(font);
286     }
287
288     /**
289      * Gets the font of this component.
290      * @return this component's font; if a font has not been set
291      * for this component, the font of its parent is returned
292      */

293     public Font getFont() {
294         Font font = super.getFont();
295
296         if (font == null && tree != null) {
297             // Strive to return a non-null value, otherwise the html support
298
// will typically pick up the wrong font in certain situations.
299
font = tree.getFont();
300         }
301         return font;
302     }
303
304     /**
305      * Subclassed to map <code>ColorUIResource</code>s to null. If
306      * <code>color</code> is null, or a <code>ColorUIResource</code>, this
307      * has the effect of letting the background color of the JTree show
308      * through. On the other hand, if <code>color</code> is non-null, and not
309      * a <code>ColorUIResource</code>, the background becomes
310      * <code>color</code>.
311      */

312     public void setBackground(Color color) {
313     if(color instanceof ColorUIResource JavaDoc)
314         color = null;
315     super.setBackground(color);
316     }
317
318     /**
319       * Configures the renderer based on the passed in components.
320       * The value is set from messaging the tree with
321       * <code>convertValueToText</code>, which ultimately invokes
322       * <code>toString</code> on <code>value</code>.
323       * The foreground color is set based on the selection and the icon
324       * is set based on on leaf and expanded.
325       */

326     public Component getTreeCellRendererComponent(JTree tree, Object JavaDoc value,
327                           boolean sel,
328                           boolean expanded,
329                           boolean leaf, int row,
330                           boolean hasFocus) {
331     String JavaDoc stringValue = tree.convertValueToText(value, sel,
332                       expanded, leaf, row, hasFocus);
333
334         this.tree = tree;
335     this.hasFocus = hasFocus;
336     setText(stringValue);
337     if(sel)
338         setForeground(getTextSelectionColor());
339     else
340         setForeground(getTextNonSelectionColor());
341     // There needs to be a way to specify disabled icons.
342
if (!tree.isEnabled()) {
343         setEnabled(false);
344         if (leaf) {
345         setDisabledIcon(getLeafIcon());
346         } else if (expanded) {
347         setDisabledIcon(getOpenIcon());
348         } else {
349         setDisabledIcon(getClosedIcon());
350         }
351     }
352     else {
353         setEnabled(true);
354         if (leaf) {
355         setIcon(getLeafIcon());
356         } else if (expanded) {
357         setIcon(getOpenIcon());
358         } else {
359         setIcon(getClosedIcon());
360         }
361     }
362         setComponentOrientation(tree.getComponentOrientation());
363         
364     selected = sel;
365
366     return this;
367     }
368
369     /**
370       * Paints the value. The background is filled based on selected.
371       */

372     public void paint(Graphics g) {
373     Color bColor;
374
375     if(selected) {
376         bColor = getBackgroundSelectionColor();
377     } else {
378         bColor = getBackgroundNonSelectionColor();
379         if(bColor == null)
380         bColor = getBackground();
381     }
382     int imageOffset = -1;
383     if(bColor != null) {
384         Icon currentI = getIcon();
385
386         imageOffset = getLabelStart();
387         g.setColor(bColor);
388         if(getComponentOrientation().isLeftToRight()) {
389             g.fillRect(imageOffset, 0, getWidth() - imageOffset,
390                getHeight());
391         } else {
392             g.fillRect(0, 0, getWidth() - imageOffset,
393                getHeight());
394         }
395     }
396
397     if (hasFocus) {
398         if (drawsFocusBorderAroundIcon) {
399         imageOffset = 0;
400         }
401         else if (imageOffset == -1) {
402         imageOffset = getLabelStart();
403         }
404         if(getComponentOrientation().isLeftToRight()) {
405         paintFocus(g, imageOffset, 0, getWidth() - imageOffset,
406                getHeight());
407         } else {
408         paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight());
409         }
410     }
411     super.paint(g);
412     }
413
414     private void paintFocus(Graphics g, int x, int y, int w, int h) {
415     Color bsColor = getBorderSelectionColor();
416
417     if (bsColor != null && (selected || !drawDashedFocusIndicator)) {
418         g.setColor(bsColor);
419         g.drawRect(x, y, w - 1, h - 1);
420     }
421     if (drawDashedFocusIndicator) {
422         Color color;
423         if (selected) {
424         color = getBackgroundSelectionColor();
425         } else {
426         color = getBackgroundNonSelectionColor();
427         if(color == null) {
428             color = getBackground();
429         }
430         }
431         
432         if (treeBGColor != color) {
433         treeBGColor = color;
434         focusBGColor = new Color(~color.getRGB());
435         }
436         g.setColor(focusBGColor);
437         BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
438     }
439     }
440
441     private int getLabelStart() {
442     Icon currentI = getIcon();
443     if(currentI != null && getText() != null) {
444         return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
445     }
446     return 0;
447     }
448
449     /**
450      * Overrides <code>JComponent.getPreferredSize</code> to
451      * return slightly wider preferred size value.
452      */

453     public Dimension getPreferredSize() {
454     Dimension retDimension = super.getPreferredSize();
455
456     if(retDimension != null)
457         retDimension = new Dimension(retDimension.width + 3,
458                      retDimension.height);
459     return retDimension;
460     }
461
462    /**
463     * Overridden for performance reasons.
464     * See the <a HREF="#override">Implementation Note</a>
465     * for more information.
466     */

467     public void validate() {}
468
469    /**
470     * Overridden for performance reasons.
471     * See the <a HREF="#override">Implementation Note</a>
472     * for more information.
473     *
474     * @since 1.5
475     */

476     public void invalidate() {}
477
478    /**
479     * Overridden for performance reasons.
480     * See the <a HREF="#override">Implementation Note</a>
481     * for more information.
482     */

483     public void revalidate() {}
484
485    /**
486     * Overridden for performance reasons.
487     * See the <a HREF="#override">Implementation Note</a>
488     * for more information.
489     */

490     public void repaint(long tm, int x, int y, int width, int height) {}
491
492    /**
493     * Overridden for performance reasons.
494     * See the <a HREF="#override">Implementation Note</a>
495     * for more information.
496     */

497     public void repaint(Rectangle r) {}
498
499    /**
500     * Overridden for performance reasons.
501     * See the <a HREF="#override">Implementation Note</a>
502     * for more information.
503     *
504     * @since 1.5
505     */

506     public void repaint() {}
507
508    /**
509     * Overridden for performance reasons.
510     * See the <a HREF="#override">Implementation Note</a>
511     * for more information.
512     */

513     protected void firePropertyChange(String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue) {
514     // Strings get interned...
515
if (propertyName=="text")
516         super.firePropertyChange(propertyName, oldValue, newValue);
517     }
518
519    /**
520     * Overridden for performance reasons.
521     * See the <a HREF="#override">Implementation Note</a>
522     * for more information.
523     */

524     public void firePropertyChange(String JavaDoc propertyName, byte oldValue, byte newValue) {}
525
526    /**
527     * Overridden for performance reasons.
528     * See the <a HREF="#override">Implementation Note</a>
529     * for more information.
530     */

531     public void firePropertyChange(String JavaDoc propertyName, char oldValue, char newValue) {}
532
533    /**
534     * Overridden for performance reasons.
535     * See the <a HREF="#override">Implementation Note</a>
536     * for more information.
537     */

538     public void firePropertyChange(String JavaDoc propertyName, short oldValue, short newValue) {}
539
540    /**
541     * Overridden for performance reasons.
542     * See the <a HREF="#override">Implementation Note</a>
543     * for more information.
544     */

545     public void firePropertyChange(String JavaDoc propertyName, int oldValue, int newValue) {}
546
547    /**
548     * Overridden for performance reasons.
549     * See the <a HREF="#override">Implementation Note</a>
550     * for more information.
551     */

552     public void firePropertyChange(String JavaDoc propertyName, long oldValue, long newValue) {}
553
554    /**
555     * Overridden for performance reasons.
556     * See the <a HREF="#override">Implementation Note</a>
557     * for more information.
558     */

559     public void firePropertyChange(String JavaDoc propertyName, float oldValue, float newValue) {}
560
561    /**
562     * Overridden for performance reasons.
563     * See the <a HREF="#override">Implementation Note</a>
564     * for more information.
565     */

566     public void firePropertyChange(String JavaDoc propertyName, double oldValue, double newValue) {}
567
568    /**
569     * Overridden for performance reasons.
570     * See the <a HREF="#override">Implementation Note</a>
571     * for more information.
572     */

573     public void firePropertyChange(String JavaDoc propertyName, boolean oldValue, boolean newValue) {}
574
575 }
576
Popular Tags