1. /*
  2. * @(#)DefaultTreeCellRenderer.java 1.32 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.tree;
  8. import javax.swing.*;
  9. import javax.swing.plaf.ColorUIResource;
  10. import javax.swing.plaf.FontUIResource;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import java.beans.*;
  14. import java.io.*;
  15. import java.util.*;
  16. /**
  17. * Displays an entry in a tree.
  18. * <p>
  19. * <strong>Warning:</strong>
  20. * Serialized objects of this class will not be compatible with
  21. * future Swing releases. The current serialization support is appropriate
  22. * for short term storage or RMI between applications running the same
  23. * version of Swing. A future release of Swing will provide support for
  24. * long term persistence.
  25. * @version 1.32 11/29/01
  26. * @author Rob Davis
  27. * @author Ray Ryan
  28. * @author Scott Violet
  29. */
  30. public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
  31. {
  32. /** Is the value currently selected. */
  33. protected boolean selected;
  34. // These two ivars will be made protected later.
  35. /** True if has focus. */
  36. private boolean hasFocus;
  37. /** True if draws focus border around icon as well. */
  38. private boolean drawsFocusBorderAroundIcon;
  39. // Icons
  40. /** Icon used to show non-leaf nodes that aren't expanded. */
  41. transient protected Icon closedIcon;
  42. /** Icon used to show leaf nodes. */
  43. transient protected Icon leafIcon;
  44. /** Icon used to show non-leaf nodes that are expanded. */
  45. transient protected Icon openIcon;
  46. // Colors
  47. /** Color to use for the foreground for selected nodes. */
  48. protected Color textSelectionColor;
  49. /** Color to use for the foreground for non-selected nodes. */
  50. protected Color textNonSelectionColor;
  51. /** Color to use for the background when a node is selected. */
  52. protected Color backgroundSelectionColor;
  53. /** Color to use for the background when the node isn't selected. */
  54. protected Color backgroundNonSelectionColor;
  55. /** Color to use for the background when the node isn't selected. */
  56. protected Color borderSelectionColor;
  57. /**
  58. * Returns a new instance of DefaultTreeCellRenderer. Alignment is
  59. * set to left aligned. Icons and text color are determined from the
  60. * UIManager.
  61. */
  62. public DefaultTreeCellRenderer() {
  63. setHorizontalAlignment(JLabel.LEFT);
  64. setLeafIcon(UIManager.getIcon("Tree.leafIcon"));
  65. setClosedIcon(UIManager.getIcon("Tree.closedIcon"));
  66. setOpenIcon(UIManager.getIcon("Tree.openIcon"));
  67. setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
  68. setTextNonSelectionColor(UIManager.getColor("Tree.textForeground"));
  69. setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
  70. setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
  71. setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
  72. Object value = UIManager.get("Tree.drawsFocusBorderAroundIcon");
  73. drawsFocusBorderAroundIcon = (value != null && ((Boolean)value).
  74. booleanValue());
  75. }
  76. /**
  77. * Returns the default icon, for the current laf, that is used to
  78. * represent non-leaf nodes that are expanded.
  79. */
  80. public Icon getDefaultOpenIcon() {
  81. return UIManager.getIcon("Tree.openIcon");
  82. }
  83. /**
  84. * Returns the default icon, for the current laf, that is used to
  85. * represent non-leaf nodes that are not expanded.
  86. */
  87. public Icon getDefaultClosedIcon() {
  88. return UIManager.getIcon("Tree.closedIcon");
  89. }
  90. /**
  91. * Returns the default icon, for the current laf, that is used to
  92. * represent leaf nodes.
  93. */
  94. public Icon getDefaultLeafIcon() {
  95. return UIManager.getIcon("Tree.leafIcon");
  96. }
  97. /**
  98. * Sets the icon used to represent non-leaf nodes that are expanded.
  99. */
  100. public void setOpenIcon(Icon newIcon) {
  101. openIcon = newIcon;
  102. }
  103. /**
  104. * Returns the icon used to represent non-leaf nodes that are expanded.
  105. */
  106. public Icon getOpenIcon() {
  107. return openIcon;
  108. }
  109. /**
  110. * Sets the icon used to represent non-leaf nodes that are not expanded.
  111. */
  112. public void setClosedIcon(Icon newIcon) {
  113. closedIcon = newIcon;
  114. }
  115. /**
  116. * Returns the icon used to represent non-leaf nodes that are not
  117. * expanded.
  118. */
  119. public Icon getClosedIcon() {
  120. return closedIcon;
  121. }
  122. /**
  123. * Sets the icon used to represent leaf nodes.
  124. */
  125. public void setLeafIcon(Icon newIcon) {
  126. leafIcon = newIcon;
  127. }
  128. /**
  129. * Returns the icon used to represent leaf nodes.
  130. */
  131. public Icon getLeafIcon() {
  132. return leafIcon;
  133. }
  134. /**
  135. * Sets the color the text is drawn with when the node is selected.
  136. */
  137. public void setTextSelectionColor(Color newColor) {
  138. textSelectionColor = newColor;
  139. }
  140. /**
  141. * Returns the color the text is drawn with when the node is selected.
  142. */
  143. public Color getTextSelectionColor() {
  144. return textSelectionColor;
  145. }
  146. /**
  147. * Sets the color the text is drawn with when the node isn't selected.
  148. */
  149. public void setTextNonSelectionColor(Color newColor) {
  150. textNonSelectionColor = newColor;
  151. }
  152. /**
  153. * Returns the color the text is drawn with when the node isn't selected.
  154. */
  155. public Color getTextNonSelectionColor() {
  156. return textNonSelectionColor;
  157. }
  158. /**
  159. * Sets the color to use for the background if node is selected.
  160. */
  161. public void setBackgroundSelectionColor(Color newColor) {
  162. backgroundSelectionColor = newColor;
  163. }
  164. /**
  165. * Returns the color to use for the background if node is selected.
  166. */
  167. public Color getBackgroundSelectionColor() {
  168. return backgroundSelectionColor;
  169. }
  170. /**
  171. * Sets the background color to be used for non selected nodes.
  172. */
  173. public void setBackgroundNonSelectionColor(Color newColor) {
  174. backgroundNonSelectionColor = newColor;
  175. }
  176. /**
  177. * Returns the background color to be used for non selected nodes.
  178. */
  179. public Color getBackgroundNonSelectionColor() {
  180. return backgroundNonSelectionColor;
  181. }
  182. /**
  183. * Sets the color to use for the border.
  184. */
  185. public void setBorderSelectionColor(Color newColor) {
  186. borderSelectionColor = newColor;
  187. }
  188. /**
  189. * Returns the color the border is drawn.
  190. */
  191. public Color getBorderSelectionColor() {
  192. return borderSelectionColor;
  193. }
  194. /**
  195. * Subclassed to only accept the font if it isn't a FontUIResource.
  196. */
  197. public void setFont(Font font) {
  198. if(font instanceof FontUIResource)
  199. font = null;
  200. super.setFont(font);
  201. }
  202. /**
  203. * Subclassed to only accept the color if it isn't a ColorUIResource.
  204. */
  205. public void setBackground(Color color) {
  206. if(color instanceof ColorUIResource)
  207. color = null;
  208. super.setBackground(color);
  209. }
  210. /**
  211. * Configures the renderer based on the passed in components.
  212. * The value is set from messaging value with toString().
  213. * The foreground color is set based on the selection and the icon
  214. * is set based on on leaf and expanded.
  215. */
  216. public Component getTreeCellRendererComponent(JTree tree, Object value,
  217. boolean sel,
  218. boolean expanded,
  219. boolean leaf, int row,
  220. boolean hasFocus) {
  221. String stringValue = tree.convertValueToText(value, sel,
  222. expanded, leaf, row, hasFocus);
  223. this.hasFocus = hasFocus;
  224. setText(stringValue);
  225. if(sel)
  226. setForeground(getTextSelectionColor());
  227. else
  228. setForeground(getTextNonSelectionColor());
  229. // There needs to be a way to specify disabled icons.
  230. if (!tree.isEnabled()) {
  231. setEnabled(false);
  232. if (leaf) {
  233. setDisabledIcon(getLeafIcon());
  234. } else if (expanded) {
  235. setDisabledIcon(getOpenIcon());
  236. } else {
  237. setDisabledIcon(getClosedIcon());
  238. }
  239. }
  240. else {
  241. setEnabled(true);
  242. if (leaf) {
  243. setIcon(getLeafIcon());
  244. } else if (expanded) {
  245. setIcon(getOpenIcon());
  246. } else {
  247. setIcon(getClosedIcon());
  248. }
  249. }
  250. selected = sel;
  251. return this;
  252. }
  253. /**
  254. * Paints the value. The background is filled based on selected.
  255. */
  256. public void paint(Graphics g) {
  257. Color bColor;
  258. if(selected) {
  259. bColor = getBackgroundSelectionColor();
  260. } else {
  261. bColor = getBackgroundNonSelectionColor();
  262. if(bColor == null)
  263. bColor = getBackground();
  264. }
  265. int imageOffset = -1;
  266. if(bColor != null) {
  267. Icon currentI = getIcon();
  268. imageOffset = getLabelStart();
  269. g.setColor(bColor);
  270. g.fillRect(imageOffset, 0, getWidth() - 1 - imageOffset,
  271. getHeight());
  272. }
  273. if (hasFocus) {
  274. if (drawsFocusBorderAroundIcon) {
  275. imageOffset = 0;
  276. }
  277. else if (imageOffset == -1) {
  278. imageOffset = getLabelStart();
  279. }
  280. Color bsColor = getBorderSelectionColor();
  281. if (bsColor != null) {
  282. g.setColor(bsColor);
  283. g.drawRect(imageOffset, 0, getWidth() - 1 - imageOffset,
  284. getHeight() - 1);
  285. }
  286. }
  287. super.paint(g);
  288. }
  289. private int getLabelStart() {
  290. Icon currentI = getIcon();
  291. if(currentI != null && getText() != null) {
  292. return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
  293. }
  294. return 0;
  295. }
  296. /**
  297. * Overrides <code>JComponent.getPreferredSize</code> to
  298. * return slightly wider preferred size value.
  299. */
  300. public Dimension getPreferredSize() {
  301. Dimension retDimension = super.getPreferredSize();
  302. if(retDimension != null)
  303. retDimension = new Dimension(retDimension.width + 3,
  304. retDimension.height);
  305. return retDimension;
  306. }
  307. }