1
14 package demo.view.orgchart;
15
16 import java.awt.BorderLayout;
17 import java.awt.Color;
18 import java.awt.Component;
19 import java.awt.Dimension;
20 import java.awt.EventQueue;
21 import java.awt.FlowLayout;
22 import java.awt.Font;
23 import java.awt.event.ActionEvent;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.BoxLayout;
33 import javax.swing.ButtonGroup;
34 import javax.swing.ImageIcon;
35 import javax.swing.JButton;
36 import javax.swing.JCheckBox;
37 import javax.swing.JComponent;
38 import javax.swing.JEditorPane;
39 import javax.swing.JFrame;
40 import javax.swing.JLabel;
41 import javax.swing.JPanel;
42 import javax.swing.JRadioButton;
43 import javax.swing.JRootPane;
44 import javax.swing.JScrollPane;
45 import javax.swing.JSplitPane;
46 import javax.swing.JTable;
47 import javax.swing.JTree;
48 import javax.swing.event.ChangeEvent;
49 import javax.swing.event.ChangeListener;
50 import javax.swing.event.TreeSelectionEvent;
51 import javax.swing.event.TreeSelectionListener;
52 import javax.swing.table.DefaultTableModel;
53 import javax.swing.tree.DefaultTreeCellRenderer;
54 import javax.swing.tree.DefaultTreeModel;
55 import javax.swing.tree.DefaultTreeSelectionModel;
56 import javax.swing.tree.TreeModel;
57 import javax.swing.tree.TreeNode;
58 import javax.swing.tree.TreePath;
59 import javax.swing.tree.TreeSelectionModel;
60
61 import demo.view.DemoDefaults;
62 import org.xml.sax.InputSource;
63
64 import demo.view.orgchart.OrgChartTreeModel.Employee;
65
66 import y.base.Node;
67 import y.base.NodeCursor;
68 import y.view.Graph2DSelectionEvent;
69 import y.view.Graph2DSelectionListener;
70 import y.view.Overview;
71
72
98 public class OrgChartDemo {
99
100 private JOrgChart orgChart;
101 private JTable propertiesTable;
102 private JTree tree;
103
104
107 public void addContentTo( final JRootPane rootPane ) {
108 final JPanel contentPane = new JPanel(new BorderLayout());
109
110 OrgChartTreeModel model = readOrgChart(getClass().getResource("resources/orgchartmodel.xml"));
111 if (model != null) {
112 Box leftPanel = new Box(BoxLayout.Y_AXIS);
113
114 orgChart = createOrgChart(model);
115 orgChart.setFitContentOnResize(true);
116
117 Overview overview = orgChart.createOverview();
118 leftPanel.add(createTitledPanel(overview, "Overview"));
119
120 tree = createStructureView(model);
121 JComponent viewOptions = createViewOptionsPanel();
122 leftPanel.add(viewOptions, BorderLayout.NORTH);
123 leftPanel.add(createTitledPanel(new JScrollPane(tree),"Structure View"));
124
125 propertiesTable = createPropertiesTable();
126 JScrollPane scrollPane = new JScrollPane(propertiesTable);
127 scrollPane.setPreferredSize(new Dimension(200, 120));
128 leftPanel.add(createTitledPanel(scrollPane,"Properties"));
129
130
131 orgChart.getGraph2D().addGraph2DSelectionListener(new OrgChartSelectionUpdater());
133 tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionUpdater());
135
137 contentPane.setLayout(new BorderLayout());
138 contentPane.add(leftPanel, BorderLayout.WEST);
139
140 JComponent helpPane = createHelpPane(getClass().getResource("resources/orgcharthelp.html"));
141 helpPane.setMinimumSize(new Dimension(200,10));
142
143 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
144 createTitledPanel(orgChart, "Organization Chart"),
145 createTitledPanel(helpPane, "Help"));
146 splitPane.setOneTouchExpandable(true);
147
148 splitPane.setResizeWeight(1);
149
150 contentPane.add(splitPane, BorderLayout.CENTER);
151 } else {
152 contentPane.setPreferredSize(new Dimension(320, 24));
153 contentPane.add(new JLabel("Could not create Organization Chart.", JLabel.CENTER));
154 }
155
156 rootPane.setContentPane(contentPane);
157 }
158
159
162 private void start() {
163 final JFrame frame = new JFrame("yFiles Organization Chart Demo");
164 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
165 addContentTo(frame.getRootPane());
166 frame.pack();
167 frame.setVisible(true);
168 orgChart.requestFocus();
169 }
170
171
174 JComponent createHelpPane(URL helpURL) {
175 try {
176 JEditorPane editorPane = new JEditorPane(helpURL);
177 editorPane.setEditable(false);
178 editorPane.setPreferredSize(new Dimension(250, 250));
179 return new JScrollPane(editorPane);
180 } catch (IOException e) {
181 e.printStackTrace();
182 }
183 return null;
184 }
185
186
189 OrgChartTreeModel readOrgChart(URL orgChartURL) {
190 OrgChartTreeModel model = null;
191 try {
192 InputStream stream = orgChartURL.openStream();
193 model = OrgChartTreeModel.create(new InputSource(stream));
194 stream.close();
195 }catch(IOException ioex) {
196 System.err.println("Failed to read from " + orgChartURL);
197 ioex.printStackTrace();
198 }
199 return model;
200 }
201
202
205 JOrgChart createOrgChart(OrgChartTreeModel model) {
206 JOrgChart orgChart = new JOrgChart(model);
207 orgChart.setPreferredSize(new Dimension(720, 750));
208 addGlassPaneComponents(orgChart);
209 return orgChart;
210 }
211
212
215 JTree createStructureView(TreeModel model) {
216 JTree tree = new JTree(model);
217 tree.setCellRenderer(new DefaultTreeCellRenderer() {
218 public Component getTreeCellRendererComponent(
219 JTree tree,Object value,boolean sel,boolean expanded,boolean leaf,int row, boolean hasFocus) {
220 if(value instanceof Employee) {
221 Employee employee = (Employee)value;
222 value = employee.name;
223 }
224 return super.getTreeCellRendererComponent(
225 tree, value, sel,
226 expanded, leaf, row,
227 hasFocus);
228 }
229 });
230
231 for(int i = 0; i < tree.getRowCount(); i++) {
232 tree.expandPath(tree.getPathForRow(i));
233 }
234
235 return tree;
236 }
237
238
241 JTable createPropertiesTable() {
242 DefaultTableModel tm = new DefaultTableModel();
243 tm.addColumn("", new Object[]{"Name", "Position", "Phone", "Fax", "Email", "Business Unit", "Status"});
244 tm.addColumn("", new Object[]{"", "", "", "", "" , "" , ""});
245 return new JTable(tm) {
246 public boolean isCellEditable(int row, int column) {
247 return false;
248 }
249 };
250 }
251
252
255 void updatePropertiesTable(Employee e) {
256 DefaultTableModel tm = (DefaultTableModel) propertiesTable.getModel();
257 tm.setValueAt(e.name, 0, 1);
258 tm.setValueAt(e.position, 1, 1);
259 tm.setValueAt(e.phone, 2, 1);
260 tm.setValueAt(e.fax, 3, 1);
261 tm.setValueAt(e.email, 4, 1);
262 tm.setValueAt(e.businessUnit, 5, 1);
263 tm.setValueAt(e.status, 6, 1);
264 }
265
266
269 JPanel createViewOptionsPanel() {
270 JPanel panel = new JPanel();
271 panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
272 final JRadioButton button1 = new JRadioButton(new AbstractAction("Global View") {
273 public void actionPerformed(ActionEvent e) {
274 orgChart.showGlobalHierarchy();
275 }
276 });
277 button1.setSelected(true);
278
279 final JRadioButton button2 = new JRadioButton(new AbstractAction("Local View") {
280 public void actionPerformed(ActionEvent e) {
281 orgChart.showLocalHierarchy(null);
282 }
283 });
284
285 ButtonGroup bg = new ButtonGroup();
286 bg.add(button1);
287 bg.add(button2);
288 panel.add(button1);
289 panel.add(button2);
290
291 final JCheckBox checkBox = new JCheckBox(new AbstractAction("Show Colleagues") {
292 public void actionPerformed(ActionEvent e) {
293 boolean result = ((JCheckBox)e.getSource()).isSelected();
294 if(result != orgChart.isSiblingViewEnabled()) {
295 orgChart.setSiblingViewEnabled(result);
296 orgChart.showLocalHierarchy(null);
297 }
298 }
299 });
300 checkBox.setEnabled(false);
301 panel.add(checkBox);
302
303 final JCheckBox checkBox2 = new JCheckBox(new AbstractAction("Show Business Units") {
304 public void actionPerformed(ActionEvent e) {
305 boolean result = ((JCheckBox)e.getSource()).isSelected();
306 if(result != orgChart.isGroupViewEnabled()) {
307 orgChart.setGroupViewEnabled(result);
308 orgChart.updateChart();
309 }
310 }
311 });
312 panel.add(checkBox2);
313
314 button2.addChangeListener(new ChangeListener() {
315 public void stateChanged(ChangeEvent e) {
316 checkBox.setEnabled(button2.isSelected());
317 }
318 });
319
320 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
321
322 return createTitledPanel(panel, "View Options");
323
324 }
325
326
329 private void addGlassPaneComponents(JOrgChart orgChart ) {
330 JPanel glassPane = orgChart.getGlassPane();
331 glassPane.setLayout(new BorderLayout());
332
333 JPanel bar = new JPanel(new FlowLayout(FlowLayout.LEFT,5,0));
334 bar.setOpaque(false);
335 bar.setBorder(BorderFactory.createEmptyBorder(20,15,0,0));
336
337 Action zoomIn = orgChart.createZoomInAction();
338 zoomIn.putValue(AbstractAction.SMALL_ICON, new ImageIcon(getClass().getResource("resources/icons/zoomIn.png")));
339 zoomIn.putValue(AbstractAction.SHORT_DESCRIPTION, "Zoom into Chart");
340 bar.add(createButton(zoomIn));
341
342 Action zoomOut = orgChart.createZoomOutAction();
343 zoomOut.putValue(AbstractAction.SMALL_ICON, new ImageIcon(getClass().getResource("resources/icons/zoomOut.png")));
344 zoomOut.putValue(AbstractAction.SHORT_DESCRIPTION, "Zoom out of Chart");
345 bar.add(createButton(zoomOut));
346
347 Action fitContent = orgChart.createFitContentAction();
348 fitContent.putValue(AbstractAction.SMALL_ICON, new ImageIcon(getClass().getResource("resources/icons/zoomFit.png")));
349 fitContent.putValue(AbstractAction.SHORT_DESCRIPTION, "Fit Chart into View");
350 bar.add(createButton(fitContent));
351
352 glassPane.add(bar, BorderLayout.NORTH);
353 }
354
355
358 private JButton createButton(Action action) {
359 JButton button = new JButton(action);
360 button.setBackground(Color.WHITE);
361 return button;
362 }
363
364
365
368 class TreeSelectionUpdater implements TreeSelectionListener {
369 public void valueChanged(TreeSelectionEvent e) {
370 TreePath path = e.getPath();
371 Employee employee = (Employee) path.getLastPathComponent();
372 Node node = orgChart.getNodeForUserObject(employee);
373
374 if(orgChart.isLocalViewEnabled() && (node == null || node.getGraph() == null)) {
375 orgChart.showLocalHierarchy(employee);
376 node = orgChart.getNodeForUserObject(employee);
377 }
378
379 if(node != null) {
380 if(e.isAddedPath()) {
381 for(NodeCursor nc = orgChart.getGraph2D().selectedNodes(); nc.ok(); nc.next()) {
382 if(nc.node() != node) {
383 orgChart.getGraph2D().setSelected(nc.node(), false);
384 }
385 }
386 if(!orgChart.getGraph2D().isSelected(node)) {
387 orgChart.getGraph2D().setSelected(node, e.isAddedPath());
388 orgChart.focusNode(node);
389 }
390 }
391 }
392 }
393 }
394
395
398 class OrgChartSelectionUpdater implements Graph2DSelectionListener {
399 public void onGraph2DSelectionEvent(Graph2DSelectionEvent e) {
400 if(e.getSubject() instanceof Node) {
401 Node node = (Node) e.getSubject();
402 Employee p = (Employee) orgChart.getUserObject(node);
403 if(p != null) {
404 syncTreeSelection(node);
405 if(orgChart.getGraph2D().isSelected(node)) {
406 updatePropertiesTable(p);
407 }
408 }
409 }
410 }
411
412 void syncTreeSelection(Node node) {
413
414 DefaultTreeSelectionModel smodel = (DefaultTreeSelectionModel) tree.getSelectionModel();
415 smodel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
416
417 DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
418 TreeNode treeNode = (TreeNode) orgChart.getTreeNode(node);
419 TreeNode[] pathToRoot = model.getPathToRoot(treeNode);
420 TreePath path = new TreePath(pathToRoot);
421
422 if(orgChart.getGraph2D().isSelected(node)) {
423 smodel.addSelectionPath(path);
424 } else {
425 smodel.removeSelectionPath(path);
426 }
427 tree.scrollPathToVisible(path);
428 }
429 }
430
431
434 public JPanel createTitledPanel(JComponent content, String title) {
435 JPanel panel = new JPanel();
436 JLabel label = new JLabel(title);
437 label.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
438 label.setBackground(new Color(231, 219,182));
439 label.setOpaque(true);
440 label.setForeground(Color.DARK_GRAY);
441 label.setFont(label.getFont().deriveFont(Font.BOLD));
442 label.setFont(label.getFont().deriveFont(13.0f));
443 panel.setLayout(new BorderLayout());
444 panel.add(label, BorderLayout.NORTH);
445 panel.add(content, BorderLayout.CENTER);
446 return panel;
447 }
448
449
452 public static void main(String[] args) {
453 EventQueue.invokeLater(new Runnable() {
454 public void run() {
455 DemoDefaults.initLnF();
456 (new OrgChartDemo()).start();
457 }
458 });
459 }
460 }
461