View Javadoc

1   /*
2    * ObjectLab, http://www.objectlab.co.uk/open is supporting JTreeMap.
3    * 
4    * Based in London, we are world leaders in the design and development 
5    * of bespoke applications for the securities financing markets.
6    * 
7    * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
8    *           ___  _     _           _   _          _
9    *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
10   *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
11   *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
12   *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
13   *                   |__/
14   *
15   *                     www.ObjectLab.co.uk
16   *
17   * $Id: JTreeMapExample.java 113 2006-12-11 19:48:24Z ekingulen $
18   * 
19   * Copyright 2006 the original author or authors.
20   *
21   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
22   * use this file except in compliance with the License. You may obtain a copy of
23   * the License at
24   *
25   * http://www.apache.org/licenses/LICENSE-2.0
26   *
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
29   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
30   * License for the specific language governing permissions and limitations under
31   * the License.
32   */
33  package net.sf.jtreemap.swing.example;
34  
35  import java.awt.BorderLayout;
36  import java.awt.CardLayout;
37  import java.awt.Color;
38  import java.awt.Container;
39  import java.awt.Dimension;
40  import java.awt.Font;
41  import java.awt.GridBagConstraints;
42  import java.awt.event.ActionEvent;
43  import java.awt.event.ActionListener;
44  import java.awt.event.WindowEvent;
45  import java.io.File;
46  import java.io.IOException;
47  import java.text.ParseException;
48  import java.util.LinkedHashMap;
49  import java.util.Locale;
50  
51  import javax.swing.BorderFactory;
52  import javax.swing.JComboBox;
53  import javax.swing.JFileChooser;
54  import javax.swing.JFrame;
55  import javax.swing.JLabel;
56  import javax.swing.JMenu;
57  import javax.swing.JMenuBar;
58  import javax.swing.JMenuItem;
59  import javax.swing.JOptionPane;
60  import javax.swing.JPanel;
61  import javax.swing.JScrollPane;
62  import javax.swing.JSplitPane;
63  import javax.swing.JTree;
64  import javax.swing.KeyStroke;
65  import javax.swing.border.EtchedBorder;
66  import javax.swing.border.TitledBorder;
67  import javax.swing.event.TreeSelectionEvent;
68  import javax.swing.event.TreeSelectionListener;
69  import javax.swing.filechooser.FileFilter;
70  import javax.swing.tree.DefaultTreeModel;
71  
72  import net.sf.jtreemap.swing.ColorProvider;
73  import net.sf.jtreemap.swing.JTreeMap;
74  import net.sf.jtreemap.swing.SplitByNumber;
75  import net.sf.jtreemap.swing.SplitBySlice;
76  import net.sf.jtreemap.swing.SplitBySortedWeight;
77  import net.sf.jtreemap.swing.SplitByWeight;
78  import net.sf.jtreemap.swing.SplitSquarified;
79  import net.sf.jtreemap.swing.SplitStrategy;
80  import net.sf.jtreemap.swing.TreeMapNode;
81  import net.sf.jtreemap.swing.provider.HSBTreeMapColorProvider;
82  import net.sf.jtreemap.swing.provider.RandomColorProvider;
83  import net.sf.jtreemap.swing.provider.RedGreenColorProvider;
84  import net.sf.jtreemap.swing.provider.ZoomPopupMenu;
85  
86  /**
87   * Test of JTreeMap
88   * 
89   * @author Laurent Dutheil
90   */
91  public class JTreeMapExample extends JFrame implements ActionListener {
92      private static final double CONSTRAINT_WEIGHTX = 0.5;
93  
94      private static final int SCROLLPANE_WIDTH = 140;
95  
96      private static final int APPLICATION_HEIGHT = 400;
97  
98      private static final int APPLICATION_WIDTH = 600;
99  
100     private static final int DEFAULT_FONT_SIZE = 16;
101 
102     private static final long serialVersionUID = 2813934810390001709L;
103 
104     private static final String EXIT = "Exit";
105 
106     private static final String OPEN_TM3_FILE = "Open TM3 File";
107 
108     private static final String OPEN_XML_FILE = "Open Xml File";
109 
110     private JTreeMap jTreeMap;
111 
112     private JTree treeView = new JTree();
113 
114     private BuilderTM3 builderTM3;
115 
116     private CardLayout cardLayout;
117 
118     private JComboBox cmbColorProvider;
119 
120     private JComboBox cmbStrategy;
121 
122     private JComboBox cmbValue;
123 
124     private JComboBox cmbWeight;
125 
126     private final LinkedHashMap<String, ColorProvider> colorProviders = new LinkedHashMap<String, ColorProvider>();
127 
128     private JPanel panelLegend;
129 
130     private JPanel panelTM3;
131 
132     private TreeMapNode root;
133 
134     private final LinkedHashMap<String, SplitStrategy> strategies = new LinkedHashMap<String, SplitStrategy>();
135 
136     private DefaultTreeModel treeModel;
137 
138     /**
139      * Constructor
140      */
141     public JTreeMapExample() {
142         root = DemoUtil.buildDemoRoot();
143 
144         jTreeMap = new JTreeMap(this.root, treeView);
145         jTreeMap.setFont(new Font(null, Font.BOLD, DEFAULT_FONT_SIZE));
146         jTreeMap.setPreferredSize(new Dimension(APPLICATION_WIDTH, APPLICATION_HEIGHT));
147         jTreeMap.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
148 
149         /* uncomment if you want to keep proportions on zooming */
150         // jTreeMap.setZoomKeepProportion(true);
151         /*
152          * uncomment if you want to change the max border between two nodes of
153          * the same level
154          */
155         // TreeMapNode.setBorder(5);
156         // add a popup menu to zoom the JTreeMap
157         new ZoomPopupMenu(this.jTreeMap);
158 
159         // init GUI
160         try {
161             initGUI();
162         } catch (final Exception ex) {
163             ex.printStackTrace();
164         }
165     }
166 
167     /**
168      * main
169      * 
170      * @param args
171      *            command line
172      */
173     public static void main(final String[] args) {
174         final JTreeMapExample example = new JTreeMapExample();
175         example.setVisible(true);
176         example.pack();
177     }
178 
179     /*
180      * (non-Javadoc)
181      * 
182      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
183      */
184     public void actionPerformed(final ActionEvent e) {
185         // Action performed for the File Menu @see addMenu()
186 
187         final String command = e.getActionCommand();
188 
189         if (OPEN_XML_FILE.equals(command)) {
190             final JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
191             final FileFilter filter = new XMLFileFilter();
192             chooser.setFileFilter(filter);
193             final int returnVal = chooser.showOpenDialog(this);
194             if (returnVal == JFileChooser.APPROVE_OPTION) {
195                 setXmlFile(chooser.getSelectedFile().getPath());
196             }
197             // create new colorProviders for the new TreeMap
198             createColorProviders();
199             // then update the lengend panel
200             updateLegendPanel();
201         } else if (OPEN_TM3_FILE.equals(command)) {
202             final JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
203             final FileFilter filter = new TM3FileFilter();
204             chooser.setFileFilter(filter);
205             final int returnVal = chooser.showOpenDialog(this);
206             if (returnVal == JFileChooser.APPROVE_OPTION) {
207                 setTm3File(chooser.getSelectedFile().getPath());
208             }
209             // create new colorProviders for the new TreeMap
210             createColorProviders();
211             // then update the lengend panel
212             updateLegendPanel();
213 
214         } else if (EXIT.equals(command)) {
215             windowClosingEvent(null);
216         }
217     }
218 
219     /**
220      * Set the tm3 file
221      * 
222      * @param path
223      *            the path of the tm3 file
224      */
225     public void setTm3File(final String path) {
226         try {
227             builderTM3 = new BuilderTM3(new File(path));
228             root = builderTM3.getRoot();
229 
230             jTreeMap.setRoot(this.root);
231             treeModel.setRoot(this.root);
232 
233             setTM3Fields();
234             panelTM3.setVisible(true);
235         } catch (final IOException e) {
236             e.printStackTrace();
237             JOptionPane.showMessageDialog(this, e.getMessage(), "File error", JOptionPane.ERROR_MESSAGE);
238         }
239     }
240 
241     /**
242      * Set the xml file corresponding to the TreeMap.dtd
243      * 
244      * @param xmlFileName
245      *            xml file name
246      */
247     public void setXmlFile(final String xmlFileName) {
248         try {
249             final BuilderXML bXml = new BuilderXML(xmlFileName);
250             root = bXml.getRoot();
251 
252             jTreeMap.setRoot(this.root);
253             treeModel.setRoot(this.root);
254 
255             panelTM3.setVisible(false);
256         } catch (final ParseException e) {
257             e.printStackTrace();
258             JOptionPane.showMessageDialog(this, e.getMessage(), "File error", JOptionPane.ERROR_MESSAGE);
259         }
260 
261     }
262 
263     /**
264      * Code to execute before closing the window
265      * 
266      * @param e
267      *            WindowEvent
268      */
269     protected void windowClosingEvent(final WindowEvent e) {
270         System.exit(0);
271     }
272 
273     private void addMenu() {
274         final JMenuBar menuBar = new JMenuBar();
275         final JMenu menu = new JMenu("File");
276 
277         JMenuItem item = new JMenuItem(OPEN_XML_FILE);
278         item.addActionListener(this);
279         item.setAccelerator(KeyStroke.getKeyStroke('O', java.awt.event.InputEvent.ALT_MASK));
280         menu.add(item);
281 
282         item = new JMenuItem(OPEN_TM3_FILE);
283         item.addActionListener(this);
284         item.setAccelerator(KeyStroke.getKeyStroke('T', java.awt.event.InputEvent.ALT_MASK));
285         menu.add(item);
286 
287         item = new JMenuItem(EXIT);
288         item.setAccelerator(KeyStroke.getKeyStroke('X', java.awt.event.InputEvent.ALT_MASK));
289         item.addActionListener(this);
290         menu.add(item);
291 
292         menuBar.add(menu);
293         setJMenuBar(menuBar);
294     }
295 
296     /**
297      * Add a splitPane with a treeview on the left and the JTreeMap on the right
298      */
299     private void addPanelCenter(final Container parent) {
300         final JSplitPane splitPaneCenter = new JSplitPane();
301         splitPaneCenter.setBorder(BorderFactory.createEmptyBorder());
302         parent.add(splitPaneCenter, BorderLayout.CENTER);
303 
304         final JScrollPane jScrollPane1 = new JScrollPane();
305         splitPaneCenter.setTopComponent(jScrollPane1);
306         splitPaneCenter.setBottomComponent(this.jTreeMap);
307 
308         treeModel = new DefaultTreeModel(this.root);
309         treeView = new JTree(this.treeModel);
310         jTreeMap.setTreeView(treeView);
311         jScrollPane1.getViewport().add(this.treeView);
312         jScrollPane1.setPreferredSize(new Dimension(SCROLLPANE_WIDTH, jTreeMap.getRoot().getHeight()));
313         treeView.addTreeSelectionListener(new TreeSelectionListener() {
314             public void valueChanged(final TreeSelectionEvent e) {
315                 // for each selected elements ont the treeView, we zoom the
316                 // JTreeMap
317                 TreeMapNode dest = (TreeMapNode) JTreeMapExample.this.treeView.getLastSelectedPathComponent();
318 
319                 // if the element is a leaf, we select the parent
320                 if (dest != null && dest.isLeaf()) {
321                     dest = (TreeMapNode) dest.getParent();
322                 }
323                 if (dest == null) {
324                     return;
325                 }
326 
327                 JTreeMapExample.this.jTreeMap.zoom(dest);
328                 JTreeMapExample.this.jTreeMap.repaint();
329             }
330         });
331     }
332 
333     /**
334      * Add a pane to choose the weight and the value for TM3 file
335      */
336     private void addPanelEast(final Container parent) {
337         GridBagConstraints gridBagConstraints;
338         panelTM3 = new JPanel();
339         parent.add(this.panelTM3, BorderLayout.EAST);
340 
341         final JPanel choicePanel = new JPanel();
342         choicePanel.setLayout(new java.awt.GridBagLayout());
343         choicePanel.setBorder(new TitledBorder("Choose the TM3 fields"));
344         panelTM3.add(choicePanel);
345 
346         final JLabel lblWeight = new JLabel(" weight : ");
347         gridBagConstraints = new java.awt.GridBagConstraints();
348         gridBagConstraints.gridx = 0;
349         gridBagConstraints.gridy = 0;
350         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
351         choicePanel.add(lblWeight, gridBagConstraints);
352 
353         cmbWeight = new JComboBox();
354         gridBagConstraints = new java.awt.GridBagConstraints();
355         gridBagConstraints.gridx = 1;
356         gridBagConstraints.gridy = 0;
357         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
358         gridBagConstraints.weightx = CONSTRAINT_WEIGHTX;
359         choicePanel.add(this.cmbWeight, gridBagConstraints);
360         cmbWeight.addActionListener(new ActionListener() {
361             public void actionPerformed(final ActionEvent e) {
362                 final JComboBox cmb = (JComboBox) e.getSource();
363                 final String field = (String) cmb.getSelectedItem();
364                 JTreeMapExample.this.builderTM3.setWeights(field);
365                 JTreeMapExample.this.repaint();
366             }
367         });
368 
369         final JLabel lblValue = new JLabel(" value : ");
370         gridBagConstraints = new java.awt.GridBagConstraints();
371         gridBagConstraints.gridx = 0;
372         gridBagConstraints.gridy = 1;
373         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
374         gridBagConstraints.weighty = 1.0;
375         choicePanel.add(lblValue, gridBagConstraints);
376 
377         cmbValue = new JComboBox();
378         gridBagConstraints = new java.awt.GridBagConstraints();
379         gridBagConstraints.gridx = 1;
380         gridBagConstraints.gridy = 1;
381         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
382         gridBagConstraints.weightx = CONSTRAINT_WEIGHTX;
383         gridBagConstraints.weighty = 1.0;
384         choicePanel.add(this.cmbValue, gridBagConstraints);
385         cmbValue.addActionListener(new ActionListener() {
386             public void actionPerformed(final ActionEvent e) {
387                 final JComboBox cmb = (JComboBox) e.getSource();
388                 final String field = (String) cmb.getSelectedItem();
389                 JTreeMapExample.this.builderTM3.setValues(field);
390                 createColorProviders();
391                 updateLegendPanel();
392                 JTreeMapExample.this.repaint();
393             }
394         });
395 
396         panelTM3.setVisible(false);
397     }
398 
399     /**
400      * add a combobox with all strategies
401      */
402     private void addPanelNorth(final Container parent) {
403         final JPanel panelNorth = new JPanel();
404         panelNorth.setBorder(BorderFactory.createEmptyBorder());
405         final JLabel lblStrategy = new JLabel();
406         lblStrategy.setText("Strategy :");
407         parent.add(panelNorth, BorderLayout.NORTH);
408         panelNorth.add(lblStrategy);
409         cmbStrategy = new JComboBox();
410         panelNorth.add(this.cmbStrategy);
411 
412         createStrategies();
413 
414         cmbStrategy.addActionListener(new ActionListener() {
415             public void actionPerformed(final ActionEvent e) {
416                 updateStrategy();
417             }
418         });
419     }
420 
421     /**
422      * add a combobox with all color providers and the legend panel
423      */
424     private void addPanelSouth(final Container parent) {
425         final JPanel southPanel = new JPanel();
426         southPanel.setLayout(new BorderLayout());
427         final JPanel jPanelLegendNorth = new JPanel();
428         final JLabel lblColorProvider = new JLabel();
429         lblColorProvider.setText("Color Provider :");
430         jPanelLegendNorth.add(lblColorProvider);
431         cmbColorProvider = new JComboBox();
432         jPanelLegendNorth.add(this.cmbColorProvider);
433         southPanel.add(jPanelLegendNorth, BorderLayout.NORTH);
434         panelLegend = new JPanel();
435         southPanel.add(this.panelLegend, BorderLayout.CENTER);
436         parent.add(southPanel, BorderLayout.SOUTH);
437         cardLayout = new CardLayout();
438         panelLegend.setLayout(this.cardLayout);
439 
440         createColorProviders();
441 
442         for (final String key : colorProviders.keySet()) {
443             cmbColorProvider.addItem(key);
444         }
445 
446         cmbColorProvider.addActionListener(new ActionListener() {
447             public void actionPerformed(final ActionEvent e) {
448                 if (JTreeMapExample.this.cmbColorProvider.getSelectedIndex() > -1) {
449                     updateLegendPanel();
450                 }
451             }
452         });
453 
454         cmbColorProvider.setSelectedIndex(0);
455     }
456 
457     protected void createColorProviders() {
458         colorProviders.put("Red Green", new RedGreenColorProvider(this.jTreeMap));
459         colorProviders.put("Random", new RandomColorProvider(jTreeMap));
460         colorProviders.put("HSB linear", new HSBTreeMapColorProvider(jTreeMap,
461                 HSBTreeMapColorProvider.ColorDistributionTypes.Linear, Color.GREEN, Color.RED));
462         colorProviders.put("HSB log", new HSBTreeMapColorProvider(jTreeMap, HSBTreeMapColorProvider.ColorDistributionTypes.Log,
463                 Color.GREEN, Color.RED));
464         colorProviders.put("HSB SquareRoot", new HSBTreeMapColorProvider(jTreeMap,
465                 HSBTreeMapColorProvider.ColorDistributionTypes.SquareRoot, Color.GREEN, Color.RED));
466         colorProviders.put("HSB CubicRoot", new HSBTreeMapColorProvider(jTreeMap,
467                 HSBTreeMapColorProvider.ColorDistributionTypes.CubicRoot, Color.GREEN, Color.RED));
468         colorProviders.put("HSB exp", new HSBTreeMapColorProvider(jTreeMap, HSBTreeMapColorProvider.ColorDistributionTypes.Exp,
469                 Color.GREEN, Color.RED));
470         for (final String key : colorProviders.keySet()) {
471             final ColorProvider cp = colorProviders.get(key);
472             panelLegend.add(cp.getLegendPanel(), key);
473         }
474     }
475 
476     private void createStrategies() {
477         strategies.put("Squarified", new SplitSquarified());
478         strategies.put("Sorted Weight", new SplitBySortedWeight());
479         strategies.put("Weight", new SplitByWeight());
480         strategies.put("Slice", new SplitBySlice());
481         strategies.put("Equal Weight", new SplitByNumber());
482         cmbStrategy.removeAllItems();
483         for (final String key : strategies.keySet()) {
484             cmbStrategy.addItem(key);
485         }
486     }
487 
488     /**
489      * init the window
490      * 
491      * @throws Exception
492      */
493     private void initGUI() throws Exception {
494         setTitle("JTreeMap Example");
495 
496         addWindowListener(new java.awt.event.WindowAdapter() {
497             @Override
498             public void windowClosing(final WindowEvent e) {
499                 windowClosingEvent(e);
500             }
501         });
502 
503         // a File menu to import other files
504         addMenu();
505 
506         // panel to choose the strategy
507         addPanelNorth(this.getContentPane());
508         // splitPane with treeView on the left and JTreeMap on the right
509         addPanelCenter(this.getContentPane());
510         // panel to choose the color provider
511         addPanelSouth(this.getContentPane());
512         // panel to choose the fields for a TM3 file
513         addPanelEast(this.getContentPane());
514 
515         // update the chosen strategy
516         updateStrategy();
517         // update the chosen color provider
518         updateLegendPanel();
519     }
520 
521     private void setTM3Fields() {
522         final String[] numberFields = builderTM3.getNumberFields();
523         final String[] cmbValues = new String[numberFields.length + 1];
524         cmbValues[0] = "";
525         for (int i = 1; i < cmbValues.length; i++) {
526             cmbValues[i] = numberFields[i - 1];
527         }
528         cmbWeight.removeAllItems();
529         cmbValue.removeAllItems();
530         for (final String item : cmbValues) {
531             cmbWeight.addItem(item);
532             cmbValue.addItem(item);
533         }
534     }
535 
536     protected void updateLegendPanel() {
537         final String key = (String) cmbColorProvider.getSelectedItem();
538         final ColorProvider cp = colorProviders.get(key);
539         if (cp != null) {
540             jTreeMap.setColorProvider(cp);
541             cardLayout.show(this.panelLegend, key);
542         }
543         JTreeMapExample.this.repaint();
544     }
545 
546     void updateStrategy() {
547         final String key = (String) cmbStrategy.getSelectedItem();
548         final SplitStrategy strat = strategies.get(key);
549         jTreeMap.setStrategy(strat);
550         jTreeMap.repaint();
551     }
552 
553     static class TM3FileFilter extends FileFilter {
554         // return true if should accept a given file
555         @Override
556         public boolean accept(final File f) {
557             if (f.isDirectory()) {
558                 return true;
559             }
560             final String path = f.getPath().toLowerCase(Locale.getDefault());
561             if (path.endsWith(".tm3")) {
562                 return true;
563             }
564             return false;
565         }
566 
567         // return a description of files
568         @Override
569         public String getDescription() {
570             return "TM3 file (*.tm3)";
571         }
572     }
573 
574     static class XMLFileFilter extends FileFilter {
575         // return true if should accept a given file
576         @Override
577         public boolean accept(final File f) {
578             if (f.isDirectory()) {
579                 return true;
580             }
581             final String path = f.getPath().toLowerCase(Locale.getDefault());
582             if (path.endsWith(".xml")) {
583                 return true;
584             }
585             return false;
586         }
587 
588         // return a description of files
589         @Override
590         public String getDescription() {
591             return "XML file (*.xml)";
592         }
593     }
594 }
595 /*
596  *                 ObjectLab is supporing JTreeMap
597  * 
598  * Based in London, we are world leaders in the design and development 
599  * of bespoke applications for the securities financing markets.
600  * 
601  * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
602  *           ___  _     _           _   _          _
603  *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
604  *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
605  *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
606  *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
607  *                   |__/
608  *
609  *                     www.ObjectLab.co.uk
610  */