1 /*
2 * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 package javax.swing.plaf.synth;
26
27 import javax.swing;
28 import javax.swing.event;
29 import java.awt;
30 import java.awt.event;
31 import java.awt.datatransfer;
32 import java.awt.dnd;
33 import java.beans;
34 import java.io;
35 import java.util;
36 import javax.swing.plaf;
37 import javax.swing.plaf.basic;
38 import javax.swing.tree;
39 import javax.swing.text.Position;
40 import sun.swing.plaf.synth;
41
42 /**
43 * Skinnable TreeUI.
44 *
45 * @author Scott Violet
46 */
47 class SynthTreeUI extends BasicTreeUI implements PropertyChangeListener,
48 SynthUI {
49 private SynthStyle style;
50 private SynthStyle cellStyle;
51
52 private SynthContext paintContext;
53
54 private boolean drawHorizontalLines;
55 private boolean drawVerticalLines;
56
57 private Object linesStyle;
58
59 private int leadRow;
60
61 private int padding;
62
63 private boolean useTreeColors;
64
65 private Icon expandedIconWrapper;
66
67 public static ComponentUI createUI(JComponent x) {
68 return new SynthTreeUI();
69 }
70
71 SynthTreeUI() {
72 expandedIconWrapper = new ExpandedIconWrapper();
73 }
74
75 public Icon getExpandedIcon() {
76 return expandedIconWrapper;
77 }
78
79 protected void installDefaults() {
80 updateStyle(tree);
81 }
82
83 private void updateStyle(JTree tree) {
84 SynthContext context = getContext(tree, ENABLED);
85 SynthStyle oldStyle = style;
86
87 style = SynthLookAndFeel.updateStyle(context, this);
88 if (style != oldStyle) {
89 Object value;
90
91 setExpandedIcon(style.getIcon(context, "Tree.expandedIcon"));
92 setCollapsedIcon(style.getIcon(context, "Tree.collapsedIcon"));
93
94 setLeftChildIndent(style.getInt(context, "Tree.leftChildIndent",
95 0));
96 setRightChildIndent(style.getInt(context, "Tree.rightChildIndent",
97 0));
98
99 drawHorizontalLines = style.getBoolean(
100 context, "Tree.drawHorizontalLines",true);
101 drawVerticalLines = style.getBoolean(
102 context, "Tree.drawVerticalLines", true);
103 linesStyle = style.get(context, "Tree.linesStyle");
104
105 value = style.get(context, "Tree.rowHeight");
106 if (value != null) {
107 LookAndFeel.installProperty(tree, "rowHeight", value);
108 }
109
110 value = style.get(context, "Tree.scrollsOnExpand");
111 LookAndFeel.installProperty(tree, "scrollsOnExpand",
112 value != null? value : Boolean.TRUE);
113
114 padding = style.getInt(context, "Tree.padding", 0);
115
116 largeModel = (tree.isLargeModel() && tree.getRowHeight() > 0);
117
118 useTreeColors = style.getBoolean(context,
119 "Tree.rendererUseTreeColors", true);
120
121 Boolean showsRootHandles = style.getBoolean(
122 context, "Tree.showsRootHandles", Boolean.TRUE);
123 LookAndFeel.installProperty(
124 tree, JTree.SHOWS_ROOT_HANDLES_PROPERTY, showsRootHandles);
125
126 if (oldStyle != null) {
127 uninstallKeyboardActions();
128 installKeyboardActions();
129 }
130 }
131 context.dispose();
132
133 context = getContext(tree, Region.TREE_CELL, ENABLED);
134 cellStyle = SynthLookAndFeel.updateStyle(context, this);
135 context.dispose();
136 }
137
138 protected void installListeners() {
139 super.installListeners();
140 tree.addPropertyChangeListener(this);
141 }
142
143 public SynthContext getContext(JComponent c) {
144 return getContext(c, getComponentState(c));
145 }
146
147 private SynthContext getContext(JComponent c, int state) {
148 return SynthContext.getContext(SynthContext.class, c,
149 SynthLookAndFeel.getRegion(c), style, state);
150 }
151
152 private Region getRegion(JTree c) {
153 return SynthLookAndFeel.getRegion(c);
154 }
155
156 private int getComponentState(JComponent c) {
157 return SynthLookAndFeel.getComponentState(c);
158 }
159
160 private SynthContext getContext(JComponent c, Region region) {
161 return getContext(c, region, getComponentState(c, region));
162 }
163
164 private SynthContext getContext(JComponent c, Region region, int state) {
165 return SynthContext.getContext(SynthContext.class, c,
166 region, cellStyle, state);
167 }
168
169 private int getComponentState(JComponent c, Region region) {
170 // Always treat the cell as selected, will be adjusted appropriately
171 // when painted.
172 return ENABLED | SELECTED;
173 }
174
175 protected TreeCellEditor createDefaultCellEditor() {
176 TreeCellRenderer renderer = tree.getCellRenderer();
177 DefaultTreeCellEditor editor;
178
179 if(renderer != null && (renderer instanceof DefaultTreeCellRenderer)) {
180 editor = new SynthTreeCellEditor(tree, (DefaultTreeCellRenderer)
181 renderer);
182 }
183 else {
184 editor = new SynthTreeCellEditor(tree, null);
185 }
186 return editor;
187 }
188
189 protected TreeCellRenderer createDefaultCellRenderer() {
190 return new SynthTreeCellRenderer();
191 }
192
193 protected void uninstallDefaults() {
194 SynthContext context = getContext(tree, ENABLED);
195
196 style.uninstallDefaults(context);
197 context.dispose();
198 style = null;
199
200 context = getContext(tree, Region.TREE_CELL, ENABLED);
201 cellStyle.uninstallDefaults(context);
202 context.dispose();
203 cellStyle = null;
204
205
206 if (tree.getTransferHandler() instanceof UIResource) {
207 tree.setTransferHandler(null);
208 }
209 }
210
211 protected void uninstallListeners() {
212 super.uninstallListeners();
213 tree.removePropertyChangeListener(this);
214 }
215
216 public void update(Graphics g, JComponent c) {
217 SynthContext context = getContext(c);
218
219 SynthLookAndFeel.update(context, g);
220 context.getPainter().paintTreeBackground(context,
221 g, 0, 0, c.getWidth(), c.getHeight());
222 paint(context, g);
223 context.dispose();
224 }
225
226 public void paintBorder(SynthContext context, Graphics g, int x,
227 int y, int w, int h) {
228 context.getPainter().paintTreeBorder(context, g, x, y, w, h);
229 }
230
231 public void paint(Graphics g, JComponent c) {
232 SynthContext context = getContext(c);
233
234 paint(context, g);
235 context.dispose();
236 }
237
238 private void updateLeadRow() {
239 leadRow = getRowForPath(tree, tree.getLeadSelectionPath());
240 }
241
242 protected void paint(SynthContext context, Graphics g) {
243 paintContext = context;
244
245 updateLeadRow();
246
247 Rectangle paintBounds = g.getClipBounds();
248 Insets insets = tree.getInsets();
249 TreePath initialPath = getClosestPathForLocation(tree, 0,
250 paintBounds.y);
251 Enumeration paintingEnumerator = treeState.getVisiblePathsFrom
252 (initialPath);
253 int row = treeState.getRowForPath(initialPath);
254 int endY = paintBounds.y + paintBounds.height;
255 TreeModel treeModel = tree.getModel();
256 SynthContext cellContext = getContext(tree, Region.TREE_CELL);
257
258 drawingCache.clear();
259
260 setHashColor(context.getStyle().getColor(context,
261 ColorType.FOREGROUND));
262
263 if (paintingEnumerator != null) {
264 // First pass, draw the rows
265
266 boolean done = false;
267 boolean isExpanded;
268 boolean hasBeenExpanded;
269 boolean isLeaf;
270 Rectangle boundsBuffer = new Rectangle();
271 Rectangle rowBounds = new Rectangle(0, 0, tree.getWidth(),0);
272 Rectangle bounds;
273 TreePath path;
274 TreeCellRenderer renderer = tree.getCellRenderer();
275 DefaultTreeCellRenderer dtcr = (renderer instanceof
276 DefaultTreeCellRenderer) ? (DefaultTreeCellRenderer)
277 renderer : null;
278
279 configureRenderer(cellContext);
280 while (!done && paintingEnumerator.hasMoreElements()) {
281 path = (TreePath)paintingEnumerator.nextElement();
282 if (path != null) {
283 isLeaf = treeModel.isLeaf(path.getLastPathComponent());
284 if (isLeaf) {
285 isExpanded = hasBeenExpanded = false;
286 }
287 else {
288 isExpanded = treeState.getExpandedState(path);
289 hasBeenExpanded = tree.hasBeenExpanded(path);
290 }
291 bounds = getPathBounds(tree, path);
292 rowBounds.y = bounds.y;
293 rowBounds.height = bounds.height;
294 paintRow(renderer, dtcr, context, cellContext, g,
295 paintBounds, insets, bounds, rowBounds, path,
296 row, isExpanded, hasBeenExpanded, isLeaf);
297 if ((bounds.y + bounds.height) >= endY) {
298 done = true;
299 }
300 }
301 else {
302 done = true;
303 }
304 row++;
305 }
306
307 // Draw the connecting lines and controls.
308 // Find each parent and have them draw a line to their last child
309 boolean rootVisible = tree.isRootVisible();
310 TreePath parentPath = initialPath;
311 parentPath = parentPath.getParentPath();
312 while (parentPath != null) {
313 paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
314 drawingCache.put(parentPath, Boolean.TRUE);
315 parentPath = parentPath.getParentPath();
316 }
317 done = false;
318 paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
319 while (!done && paintingEnumerator.hasMoreElements()) {
320 path = (TreePath)paintingEnumerator.nextElement();
321 if (path != null) {
322 isLeaf = treeModel.isLeaf(path.getLastPathComponent());
323 if (isLeaf) {
324 isExpanded = hasBeenExpanded = false;
325 }
326 else {
327 isExpanded = treeState.getExpandedState(path);
328 hasBeenExpanded = tree.hasBeenExpanded(path);
329 }
330 bounds = getPathBounds(tree, path);
331 // See if the vertical line to the parent has been drawn.
332 parentPath = path.getParentPath();
333 if (parentPath != null) {
334 if (drawingCache.get(parentPath) == null) {
335 paintVerticalPartOfLeg(g, paintBounds, insets,
336 parentPath);
337 drawingCache.put(parentPath, Boolean.TRUE);
338 }
339 paintHorizontalPartOfLeg(g,
340 paintBounds, insets, bounds,
341 path, row, isExpanded,
342 hasBeenExpanded, isLeaf);
343 }
344 else if (rootVisible && row == 0) {
345 paintHorizontalPartOfLeg(g,
346 paintBounds, insets, bounds,
347 path, row, isExpanded,
348 hasBeenExpanded, isLeaf);
349 }
350 if (shouldPaintExpandControl(path, row, isExpanded,
351 hasBeenExpanded, isLeaf)) {
352 paintExpandControl(g, paintBounds,
353 insets, bounds, path, row,
354 isExpanded, hasBeenExpanded,isLeaf);
355 }
356 if ((bounds.y + bounds.height) >= endY) {
357 done = true;
358 }
359 }
360 else {
361 done = true;
362 }
363 row++;
364 }
365 }
366 cellContext.dispose();
367
368 paintDropLine(g);
369
370 // Empty out the renderer pane, allowing renderers to be gc'ed.
371 rendererPane.removeAll();
372 }
373
374 private boolean isDropLine(JTree.DropLocation loc) {
375 return loc != null && loc.getPath() != null && loc.getChildIndex() != -1;
376 }
377
378 private void paintDropLine(Graphics g) {
379 JTree.DropLocation loc = tree.getDropLocation();
380 if (!isDropLine(loc)) {
381 return;
382 }
383
384 Color c = (Color)style.get(paintContext, "Tree.dropLineColor");
385 if (c != null) {
386 g.setColor(c);
387 Rectangle rect = getDropLineRect(loc);
388 g.fillRect(rect.x, rect.y, rect.width, rect.height);
389 }
390 }
391
392 private Rectangle getDropLineRect(JTree.DropLocation loc) {
393 Rectangle rect = null;
394 TreePath path = loc.getPath();
395 int index = loc.getChildIndex();
396 boolean ltr = tree.getComponentOrientation().isLeftToRight();
397
398 Insets insets = tree.getInsets();
399
400 if (tree.getRowCount() == 0) {
401 rect = new Rectangle(insets.left,
402 insets.top,
403 tree.getWidth() - insets.left - insets.right,
404 0);
405 } else {
406 int row = tree.getRowForPath(path);
407 TreeModel model = getModel();
408 Object root = model.getRoot();
409
410 if (path.getLastPathComponent() == root
411 && index >= model.getChildCount(root)) {
412
413 rect = tree.getRowBounds(tree.getRowCount() - 1);
414 rect.y = rect.y + rect.height;
415 Rectangle xRect;
416
417 if (!tree.isRootVisible()) {
418 xRect = tree.getRowBounds(0);
419 } else if (model.getChildCount(root) == 0){
420 xRect = tree.getRowBounds(0);
421 xRect.x += totalChildIndent;
422 xRect.width -= totalChildIndent + totalChildIndent;
423 } else {
424 TreePath lastChildPath = path.pathByAddingChild(
425 model.getChild(root, model.getChildCount(root) - 1));
426 xRect = tree.getPathBounds(lastChildPath);
427 }
428
429 rect.x = xRect.x;
430 rect.width = xRect.width;
431 } else {
432 rect = tree.getPathBounds(path.pathByAddingChild(
433 model.getChild(path.getLastPathComponent(), index)));
434 }
435 }
436
437 if (rect.y != 0) {
438 rect.y--;
439 }
440
441 if (!ltr) {
442 rect.x = rect.x + rect.width - 100;
443 }
444
445 rect.width = 100;
446 rect.height = 2;
447
448 return rect;
449 }
450
451 private void configureRenderer(SynthContext context) {
452 TreeCellRenderer renderer = tree.getCellRenderer();
453
454 if (renderer instanceof DefaultTreeCellRenderer) {
455 DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)renderer;
456 SynthStyle style = context.getStyle();
457
458 context.setComponentState(ENABLED | SELECTED);
459 Color color = r.getTextSelectionColor();
460 if (color == null || (color instanceof UIResource)) {
461 r.setTextSelectionColor(style.getColor(
462 context, ColorType.TEXT_FOREGROUND));
463 }
464 color = r.getBackgroundSelectionColor();
465 if (color == null || (color instanceof UIResource)) {
466 r.setBackgroundSelectionColor(style.getColor(
467 context, ColorType.TEXT_BACKGROUND));
468 }
469
470 context.setComponentState(ENABLED);
471 color = r.getTextNonSelectionColor();
472 if (color == null || color instanceof UIResource) {
473 r.setTextNonSelectionColor(style.getColorForState(
474 context, ColorType.TEXT_FOREGROUND));
475 }
476 color = r.getBackgroundNonSelectionColor();
477 if (color == null || color instanceof UIResource) {
478 r.setBackgroundNonSelectionColor(style.getColorForState(
479 context, ColorType.TEXT_BACKGROUND));
480 }
481 }
482 }
483
484 protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
485 Insets insets, Rectangle bounds,
486 TreePath path, int row,
487 boolean isExpanded,
488 boolean hasBeenExpanded, boolean
489 isLeaf) {
490 if (drawHorizontalLines) {
491 super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,
492 path, row, isExpanded,
493 hasBeenExpanded, isLeaf);
494 }
495 }
496
497 protected void paintHorizontalLine(Graphics g, JComponent c, int y,
498 int left, int right) {
499 paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
500 paintContext, "Tree.horizontalLine", g, left, y, right, y, linesStyle);
501 }
502
503 protected void paintVerticalPartOfLeg(Graphics g,
504 Rectangle clipBounds, Insets insets,
505 TreePath path) {
506 if (drawVerticalLines) {
507 super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
508 }
509 }
510
511 protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
512 int bottom) {
513 paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
514 paintContext, "Tree.verticalLine", g, x, top, x, bottom, linesStyle);
515 }
516
517 protected void paintRow(TreeCellRenderer renderer,
518 DefaultTreeCellRenderer dtcr, SynthContext treeContext,
519 SynthContext cellContext, Graphics g, Rectangle clipBounds,
520 Insets insets, Rectangle bounds, Rectangle rowBounds,
521 TreePath path, int row, boolean isExpanded,
522 boolean hasBeenExpanded, boolean isLeaf) {
523 // Don't paint the renderer if editing this row.
524 boolean selected = tree.isRowSelected(row);
525
526 JTree.DropLocation dropLocation = (JTree.DropLocation)tree.getDropLocation();
527 boolean isDrop = dropLocation != null
528 && dropLocation.getChildIndex() == -1
529 && path == dropLocation.getPath();
530
531 if (selected || isDrop) {
532 cellContext.setComponentState(ENABLED | SELECTED);
533 }
534 else {
535 cellContext.setComponentState(ENABLED);
536 }
537 if (dtcr != null && (dtcr.getBorderSelectionColor() instanceof
538 UIResource)) {
539 dtcr.setBorderSelectionColor(style.getColor(
540 cellContext, ColorType.FOCUS));
541 }
542 SynthLookAndFeel.updateSubregion(cellContext, g, rowBounds);
543 cellContext.getPainter().paintTreeCellBackground(cellContext, g,
544 rowBounds.x, rowBounds.y, rowBounds.width,
545 rowBounds.height);
546 cellContext.getPainter().paintTreeCellBorder(cellContext, g,
547 rowBounds.x, rowBounds.y, rowBounds.width,
548 rowBounds.height);
549 if (editingComponent != null && editingRow == row) {
550 return;
551 }
552
553 int leadIndex;
554
555 if (tree.hasFocus()) {
556 leadIndex = leadRow;
557 }
558 else {
559 leadIndex = -1;
560 }
561
562 Component component = renderer.getTreeCellRendererComponent(
563 tree, path.getLastPathComponent(),
564 selected, isExpanded, isLeaf, row,
565 (leadIndex == row));
566
567 rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y,
568 bounds.width, bounds.height, true);
569 }
570
571 private int findCenteredX(int x, int iconWidth) {
572 return tree.getComponentOrientation().isLeftToRight()
573 ? x - (int)Math.ceil(iconWidth / 2.0)
574 : x - (int)Math.floor(iconWidth / 2.0);
575 }
576
577 protected void drawCentered(Component c, Graphics graphics, Icon icon,
578 int x, int y) {
579 int w = SynthIcon.getIconWidth(icon, paintContext);
580 int h = SynthIcon.getIconHeight(icon, paintContext);
581
582 SynthIcon.paintIcon(icon, paintContext, graphics,
583 findCenteredX(x, w),
584 y - h/2, w, h);
585 }
586
587 public void propertyChange(PropertyChangeEvent event) {
588 if (SynthLookAndFeel.shouldUpdateStyle(event)) {
589 updateStyle((JTree)event.getSource());
590 }
591
592 if ("dropLocation" == event.getPropertyName()) {
593 JTree.DropLocation oldValue = (JTree.DropLocation)event.getOldValue();
594 repaintDropLocation(oldValue);
595 repaintDropLocation(tree.getDropLocation());
596 }
597 }
598
599 private void repaintDropLocation(JTree.DropLocation loc) {
600 if (loc == null) {
601 return;
602 }
603
604 Rectangle r;
605
606 if (isDropLine(loc)) {
607 r = getDropLineRect(loc);
608 } else {
609 r = tree.getPathBounds(loc.getPath());
610 if (r != null) {
611 r.x = 0;
612 r.width = tree.getWidth();
613 }
614 }
615
616 if (r != null) {
617 tree.repaint(r);
618 }
619 }
620
621 protected int getRowX(int row, int depth) {
622 return super.getRowX(row, depth) + padding;
623 }
624
625
626 private class SynthTreeCellRenderer extends DefaultTreeCellRenderer
627 implements UIResource {
628 SynthTreeCellRenderer() {
629 }
630 public String getName() {
631 return "Tree.cellRenderer";
632 }
633 public Component getTreeCellRendererComponent(JTree tree, Object value,
634 boolean sel,
635 boolean expanded,
636 boolean leaf, int row,
637 boolean hasFocus) {
638 if (!useTreeColors && (sel || hasFocus)) {
639 SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
640 getUIOfType(getUI(), SynthLabelUI.class),
641 sel, hasFocus, tree.isEnabled(), false);
642 }
643 else {
644 SynthLookAndFeel.resetSelectedUI();
645 }
646 return super.getTreeCellRendererComponent(tree, value, sel,
647 expanded, leaf, row, hasFocus);
648 }
649 public void paint(Graphics g) {
650 paintComponent(g);
651 if (hasFocus) {
652 SynthContext context = getContext(tree, Region.TREE_CELL);
653
654 if (context.getStyle() == null) {
655 assert false: "SynthTreeCellRenderer is being used " +
656 "outside of UI that created it";
657 return;
658 }
659 int imageOffset = 0;
660 Icon currentI = getIcon();
661
662 if(currentI != null && getText() != null) {
663 imageOffset = currentI.getIconWidth() +
664 Math.max(0, getIconTextGap() - 1);
665 }
666 if (selected) {
667 context.setComponentState(ENABLED | SELECTED);
668 }
669 else {
670 context.setComponentState(ENABLED);
671 }
672 if(getComponentOrientation().isLeftToRight()) {
673 context.getPainter().paintTreeCellFocus(context, g,
674 imageOffset, 0, getWidth() - imageOffset,
675 getHeight());
676 }
677 else {
678 context.getPainter().paintTreeCellFocus(context, g,
679 0, 0, getWidth() - imageOffset, getHeight());
680 }
681 context.dispose();
682 }
683 SynthLookAndFeel.resetSelectedUI();
684 }
685 }
686
687
688 private static class SynthTreeCellEditor extends DefaultTreeCellEditor {
689 public SynthTreeCellEditor(JTree tree,
690 DefaultTreeCellRenderer renderer) {
691 super(tree, renderer);
692 setBorderSelectionColor(null);
693 }
694
695 protected TreeCellEditor createTreeCellEditor() {
696 JTextField tf = new JTextField() {
697 public String getName() {
698 return "Tree.cellEditor";
699 }
700 };
701 DefaultCellEditor editor = new DefaultCellEditor(tf);
702
703 // One click to edit.
704 editor.setClickCountToStart(1);
705 return editor;
706 }
707 }
708
709
710 //
711 // BasicTreeUI directly uses expandIcon outside of the Synth methods.
712 // To get the correct context we return an instance of this that fetches
713 // the SynthContext as needed.
714 //
715 private class ExpandedIconWrapper extends SynthIcon {
716 public void paintIcon(SynthContext context, Graphics g, int x,
717 int y, int w, int h) {
718 if (context == null) {
719 context = getContext(tree);
720 SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
721 context.dispose();
722 }
723 else {
724 SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
725 }
726 }
727
728 public int getIconWidth(SynthContext context) {
729 int width;
730 if (context == null) {
731 context = getContext(tree);
732 width = SynthIcon.getIconWidth(expandedIcon, context);
733 context.dispose();
734 }
735 else {
736 width = SynthIcon.getIconWidth(expandedIcon, context);
737 }
738 return width;
739 }
740
741 public int getIconHeight(SynthContext context) {
742 int height;
743 if (context == null) {
744 context = getContext(tree);
745 height = SynthIcon.getIconHeight(expandedIcon, context);
746 context.dispose();
747 }
748 else {
749 height = SynthIcon.getIconHeight(expandedIcon, context);
750 }
751 return height;
752 }
753 }
754 }