1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.gui.platform.swing.builder.components;
17
18 import java.awt.Component;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import javax.swing.Icon;
23 import javax.swing.JLabel;
24 import javax.swing.JTree;
25 import javax.swing.tree.DefaultTreeCellRenderer;
26
27 import net.sf.jguiraffe.gui.builder.components.tags.TreeIconHandler;
28
29 import org.apache.commons.configuration.tree.ConfigurationNode;
30
31 /**
32 * <p>
33 * A specialized tree renderer implementation.
34 * </p>
35 * <p>
36 * This class has the following tasks:
37 * <ul>
38 * <li>Obtaining the correct text for a tree node. Because a hierarchical
39 * configuration serves as data model for a tree we have to deal with
40 * <code>ConfigurationNode</code> objects. The name of such a node is used as
41 * text for a tree node.</li>
42 * <li>Determining the icon to be displayed for a tree node. This is done in
43 * collaboration with a {@link TreeIconHandler} object and the actual icons
44 * defined for a tree. For each node to display the renderer asks the
45 * {@link TreeIconHandler} for the name of the icon to use for this node. Then
46 * in looks up the corresponding icon in the map of icons associated with the
47 * current tree. If an icon is found, it is displayed. Otherwise the default
48 * icon for the current node type (leaf or branch node, expanded or not) is
49 * used.</li>
50 * </ul>
51 * </p>
52 * <p>
53 * Implementation node: This class is used internally only. Therefore, it does
54 * not do any sophisticated checks for parameters or other things.
55 * </p>
56 *
57 * @author Oliver Heger
58 * @version $Id: SwingTreeCellRenderer.java 205 2012-01-29 18:29:57Z oheger $
59 */
60 class SwingTreeCellRenderer extends DefaultTreeCellRenderer
61 {
62 /**
63 * The serial version UID.
64 */
65 private static final long serialVersionUID = -6276822538915250422L;
66
67 /** Stores the icon handler. */
68 private final TreeIconHandler iconHandler;
69
70 /** Stores the map with the known icons. */
71 private final Map<String, Icon> iconMap;
72
73 /** The tree node formatter. */
74 private final SwingTreeNodeFormatter nodeFormatter;
75
76 /**
77 * Creates a new instance of {@code SwingTreeCellRenderer} and
78 * initializes it.
79 *
80 * @param handler the icon handler (must not be <b>null</b>)
81 * @param icons a map with icons (must not be <b>null</b>)
82 * @param fmt the formatter for nodes (must not be <b>null</b>)
83 */
84 public SwingTreeCellRenderer(TreeIconHandler handler,
85 Map<String, Object> icons, SwingTreeNodeFormatter fmt)
86 {
87 iconHandler = handler;
88 iconMap = initIconMap(icons);
89 nodeFormatter = fmt;
90 }
91
92 /**
93 * Returns the {@code SwingTreeNodeFormatter} used by this renderer.
94 *
95 * @return the {@code SwingTreeNodeFormatter}
96 */
97 public SwingTreeNodeFormatter getNodeFormatter()
98 {
99 return nodeFormatter;
100 }
101
102 /**
103 * Returns the <code>TreeIconHandler</code> used by this renderer.
104 *
105 * @return the tree icon handler
106 */
107 public TreeIconHandler getIconHandler()
108 {
109 return iconHandler;
110 }
111
112 /**
113 * Returns the icon for the specified name. Result can be <b>null</b> if no
114 * icon is associated with the given name.
115 *
116 * @param name the name of the icon
117 * @return the corresponding icon or <b>null</b>
118 */
119 public Icon getTreeIcon(String name)
120 {
121 return iconMap.get(name);
122 }
123
124 /**
125 * Returns the component to be used for displaying the current cell of the
126 * tree. This implementation calls the inherited method for obtaining a
127 * partially initialized renderer component. Then, with the help of the
128 * <code>textForNode()</code> method and the
129 * {@link TreeIconHandler, it takes care of the text and the
130 * icon to be used for this cell.
131 *
132 * @param tree the tree
133 * @param value the data object representing the current cell
134 * @param selected the selected flag
135 * @param expanded a flag whether this node is expanded
136 * @param leaf a flag whether this node is a leaf node
137 * @param row the row number
138 * @param hasFocus a flag whether this cell has the focus
139 * @return the renderer component
140 */
141 @Override
142 public Component getTreeCellRendererComponent(JTree tree, Object value,
143 boolean selected, boolean expanded, boolean leaf, int row,
144 boolean hasFocus)
145 {
146 JLabel c = (JLabel) super.getTreeCellRendererComponent(tree, value,
147 selected, expanded, leaf, row, hasFocus);
148 c.setText(getNodeFormatter().textForNode(value));
149
150 String iconName = getIconHandler().getIconName(
151 (ConfigurationNode) value, expanded, leaf);
152 Icon icon = getTreeIcon(iconName);
153 if (icon != null)
154 {
155 c.setIcon(icon);
156 }
157
158 return c;
159 }
160
161 /**
162 * Transforms the icons map passed to the constructor into a map with Swing
163 * icons. In addition a copy of the map is created.
164 *
165 * @param icons the original map with the icons that was passed to the
166 * constructor
167 * @return the transformed icon map
168 */
169 private Map<String, Icon> initIconMap(Map<String, Object> icons)
170 {
171 Map<String, Icon> result = new HashMap<String, Icon>();
172
173 for (Map.Entry<String, Object> e : icons.entrySet())
174 {
175 result.put(e.getKey(), (Icon) e.getValue());
176 }
177
178 return result;
179 }
180 }