1
14 package demo.view.orgchart;
15
16 import java.awt.Component;
17 import java.awt.Graphics;
18 import java.awt.Graphics2D;
19 import java.awt.Image;
20 import java.awt.RenderingHints;
21 import java.io.IOException;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Map;
29
30 import javax.swing.Icon;
31 import javax.swing.ImageIcon;
32 import javax.swing.tree.DefaultMutableTreeNode;
33 import javax.swing.tree.DefaultTreeModel;
34 import javax.xml.parsers.DocumentBuilderFactory;
35 import javax.xml.parsers.ParserConfigurationException;
36
37 import org.w3c.dom.Document;
38 import org.w3c.dom.NamedNodeMap;
39 import org.w3c.dom.Node;
40 import org.w3c.dom.NodeList;
41 import org.xml.sax.InputSource;
42 import org.xml.sax.SAXException;
43
44
47 public class OrgChartTreeModel extends DefaultTreeModel {
48
49
52 public OrgChartTreeModel(Employee root) {
53 super(root);
54 }
55
56
59 public static class Employee extends DefaultMutableTreeNode {
60 public String name;
61 public String email;
62 public String phone;
63 public String fax;
64 public String businessUnit;
65 public String position;
66 public String status;
67 public Icon icon;
68 public String assistant;
69 public String layout;
70 }
71
72
76 public static OrgChartTreeModel create(InputSource input) {
77 OrgChartReader reader = new OrgChartReader();
78 return reader.read(input);
79 }
80
81
84 static class OrgChartReader {
85
86 OrgChartTreeModel model;
87
88 static Map userIcons;
89 static {
90 userIcons = new HashMap();
91 for(int type = 0; type <= 1; type++) {
92 String gender = type == 0 ? "male" : "female";
93 for(int user = 1; user <= 3; user++) {
94 String key = "usericon_" + gender + user;
95 ArrayList urls = new ArrayList(4);
96 int size = 256;
97 urls.add(OrgChartReader.class.getResource("resources/icons/" + key + "_" + size + ".png"));
99 userIcons.put(key,new MultiResolutionImageIcon(urls, 55,64));
101 }
102 };
103 }
104
105 public OrgChartTreeModel read(InputSource input) {
106 Document doc;
107
108 try {
109 doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
110 Employee treeRoot = visit(doc);
111 OrgChartTreeModel model = new OrgChartTreeModel(treeRoot);
112 return model;
113 } catch (SAXException e) {
114 e.printStackTrace();
115 } catch (IOException e) {
116 e.printStackTrace();
117 } catch (ParserConfigurationException e) {
118 e.printStackTrace();
119 }
120 return null;
121 }
122
123 public Employee visit(Node node)
124 {
125 String nodeName = node.getNodeName();
126 Employee employee = null;
127 if("employee".equals(nodeName)) {
128 employee = new Employee();
129
130 NamedNodeMap attributes = node.getAttributes();
131 Node attr = attributes.getNamedItem("name");
132 if(attr != null) {
133 employee.name = attr.getNodeValue();
134 }
135 attr = attributes.getNamedItem("layout");
136 if(attr != null) {
137 employee.layout = attr.getNodeValue();
138 }
139 attr = attributes.getNamedItem("email");
140 if(attr != null) {
141 employee.email = attr.getNodeValue();
142 }
143 attr = attributes.getNamedItem("phone");
144 if(attr != null) {
145 employee.phone = attr.getNodeValue();
146 }
147 attr = attributes.getNamedItem("position");
148 if(attr != null) {
149 employee.position = attr.getNodeValue();
150 }
151 attr = attributes.getNamedItem("fax");
152 if(attr != null) {
153 employee.fax = attr.getNodeValue();
154 }
155 attr = attributes.getNamedItem("businessUnit");
156 if(attr != null) {
157 employee.businessUnit = attr.getNodeValue();
158 }
159 attr = attributes.getNamedItem("status");
160 if(attr != null) {
161 String status = attr.getNodeValue();
162 employee.status = status;
163 }
164 attr = attributes.getNamedItem("icon");
165 if(attr != null) {
166 String iconName = attr.getNodeValue();
167 employee.icon = (Icon) userIcons.get(iconName);
168 }
169 attr = attributes.getNamedItem("assistant");
170 if(attr != null) {
171 employee.assistant = attr.getNodeValue();
172 }
173 }
174 NodeList nl = node.getChildNodes();
175 for(int i=0, cnt=nl.getLength(); i<cnt; i++)
176 {
177 Node n = nl.item(i);
178 Employee childNode = visit(n);
179 if(childNode != null && employee != null) {
180 employee.add(childNode);
181 }
182 if(childNode != null && employee == null) {
183 return childNode;
184 }
185 }
186 return employee;
187 }
188 }
189
190
194 static class FixedSizeImageIcon extends ImageIcon {
195
196 int width;
197 int height;
198
199 public FixedSizeImageIcon(URL imageURL, int width, int height) {
200 super(imageURL);
201 this.width = width;
202 this.height = height;
203 }
204
205 public int getIconHeight() {
206 return height;
207 }
208
209 public int getIconWidth() {
210 return width;
211 }
212
213 public void paintIcon(Component c, Graphics gfx, int x, int y) {
214 Image image = getImage();
215 Graphics2D g2d = (Graphics2D) gfx.create();
216 Object hint = g2d.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
217 g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
218 gfx.drawImage(image, x, y, getIconWidth(), getIconHeight(), c);
219 }
220 }
221
222
228 static class MultiResolutionImageIcon implements Icon {
229
230 int width;
231 int height;
232 ArrayList entries;
233
234 static class Entry {
235 double ratio;
236 Icon icon;
237 URL url;
238 }
239
240 public MultiResolutionImageIcon(URL[] imageURLs, int width, int height) {
241 this(Arrays.asList(imageURLs), width, height);
242 }
243
244 public MultiResolutionImageIcon(Collection imageURLs, int width, int height) {
245 entries = new ArrayList(imageURLs.size());
246 for(Iterator iter = imageURLs.iterator(); iter.hasNext(); ) {
247 URL imageURL = (URL) iter.next();
248 ImageIcon icon = new FixedSizeImageIcon(imageURL, width,height);
249 Image image = icon.getImage();
250 double w = image.getWidth(null);
251 double h = image.getHeight(null);
252 double ratio = Math.min(w/width, h/height);
253 Entry entry = new Entry();
254 entry.ratio = ratio;
255 entry.icon = icon;
256 entry.url = imageURL;
257 entries.add(entry);
258 }
259 this.width = width;
260 this.height = height;
261 }
262
263 public int getIconHeight() {
264 return height;
265 }
266
267 public int getIconWidth() {
268 return width;
269 }
270
271 public void paintIcon(Component c, Graphics gfx, int x, int y) {
272 Graphics2D g2d = (Graphics2D) gfx;
273 double scale = g2d.getTransform().getScaleX();
274 Entry bestEntry = null;
275 double bestDelta = Double.MAX_VALUE;
276 for(int i = 0; i < entries.size(); i++) {
277 Entry entry = (Entry) entries.get(i);
278 double ratio = entry.ratio;
279 double delta = Math.abs(ratio-scale);
280 if(delta < bestDelta) {
281 bestDelta = delta;
282 bestEntry = entry;
283 }
284 }
285 if(bestEntry != null) {
286 bestEntry.icon.paintIcon(c, gfx, x,y);
287 }
288 }
289 }
290
291 }
292