Merge branch 'master' of feistymeow.org:feisty_meow
[feisty_meow.git] / kona / src / org / feistymeow / dragdrop / dragdrop_tree_test.java
1 package org.feistymeow.dragdrop;
2
3 import java.awt.*;
4 import java.io.*;
5 import java.util.*;
6 import java.util.List;
7 import java.awt.event.*;
8 import javax.swing.*;
9 import javax.swing.event.*;
10 import javax.swing.tree.DefaultMutableTreeNode;
11 import javax.swing.tree.DefaultTreeCellRenderer;
12 import javax.swing.tree.DefaultTreeModel;
13 import javax.swing.tree.DefaultTreeSelectionModel;
14 import javax.swing.tree.MutableTreeNode;
15 import javax.swing.tree.TreeCellRenderer;
16 import javax.swing.tree.TreePath;
17 import javax.swing.tree.TreeSelectionModel;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.log4j.PropertyConfigurator;
22
23 /**
24  * A demo of the DragonDropHandler being used with a JTree.
25  * 
26  * @author Chris Koeritz
27  * @copyright Copyright (c) 2012-$now By University of Virginia
28  * @license This file is free software; you can modify and redistribute it under the terms of the
29  *          Apache License v2.0: http://www.apache.org/licenses/LICENSE-2.0
30  */
31 @SuppressWarnings("serial")
32 public class dragdrop_tree_test extends JFrame implements TreeSelectionListener
33 {
34     private DraggableDroppableTree larch;
35     private JTextField fileName;
36     static private Log logger = LogFactory.getLog(dragdrop_tree_test.DraggableDroppableTree.class);
37
38     public dragdrop_tree_test(String startPath)
39     {
40         super("dragdrop_test");
41
42         // create the tree, configure it to show our hashtable nodes, and put it in
43         // a scroll pane.
44         larch = new DraggableDroppableTree(startPath);
45         DefaultTreeModel treeModel = (DefaultTreeModel) larch.getModel();
46         larch.setCellRenderer(new CustomCellRenderer());
47         TreeSelectionModel selmod = new DefaultTreeSelectionModel();
48         selmod.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
49         larch.setSelectionModel(selmod);
50         larch.addTreeSelectionListener(this);
51         JScrollPane listScrollPane = new JScrollPane(larch);
52         // get the files that live in the specified directory.
53         String dirName = startPath + "/"; // make sure we think of it as a
54                                           // directory.
55         String filelist[] = new File(dirName).list();
56         MutableTreeNode root_node = (MutableTreeNode) treeModel.getRoot();
57         if (root_node == null) {
58             logger.error("something is not right about tree.  has null root.");
59             System.exit(1);
60         }
61         // load up the tree with the files in the directory they passed.
62         for (int i = 0; i < filelist.length; i++) {
63             String thisFileSt = dirName + filelist[i];
64             File thisFile = new File(thisFileSt);
65             // skip directories for now.
66             if (thisFile.isDirectory())
67                 continue;
68             // skip dot files.
69             if (filelist[i].startsWith("."))
70                 continue;
71             try {
72                 // need to trap exceptions from the URI/URL functions.
73                 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(makeNode(
74                         thisFile.getName(), thisFile.toURI().toURL().toString(),
75                         thisFile.getAbsolutePath()));
76                 treeModel.insertNodeInto(newNode, root_node, root_node.getChildCount());
77             } catch (java.net.MalformedURLException e) {
78                 logger.warn("caught an exception while trying to process path: "
79                         + thisFile.getAbsolutePath());
80             }
81         }
82
83         // set our status bar to have the current path info.
84         fileName = new JTextField(50);
85         // select the root.
86         larch.setSelectionPath(larch.getPathForRow(0));
87
88         // pop out all the nodes.
89         larch.expandAll();
90
91         // Create a panel that uses FlowLayout (the default).
92         JPanel buttonPane = new JPanel();
93         buttonPane.add(fileName);
94
95         Container contentPane = getContentPane();
96         contentPane.add(listScrollPane, BorderLayout.CENTER);
97         contentPane.add(buttonPane, BorderLayout.NORTH);
98     }
99
100     @SuppressWarnings("unchecked")
101     // given a mutable tree node, this will fetch out the embedded hash table.
102     Hashtable<String, String> NodeToTable(Object node)
103     {
104         if (!(node instanceof DefaultMutableTreeNode))
105             return null;
106         Object content = ((DefaultMutableTreeNode) node).getUserObject();
107         if (content != null) {
108             if (content instanceof Hashtable<?, ?>) {
109                 try {
110                     return (Hashtable<String, String>) content;
111                 } catch (Throwable cause) {
112                     logger.error("failed to cast our tree node to a hashtable.");
113                 }
114             }
115         }
116         return null;
117     }
118
119     public void valueChanged(TreeSelectionEvent e)
120     {
121         fileName.setText("");
122         TreePath sel_path = larch.getSelectionPath();
123         if (sel_path != null) {
124             Hashtable<String, String> table = NodeToTable(sel_path.getLastPathComponent());
125             if (table != null) {
126                 String name = (String) table.get("name");
127                 fileName.setText(name);
128             }
129         }
130     }
131
132     private static Hashtable<String, String> makeNode(String name, String url, String strPath)
133     {
134         Hashtable<String, String> hashtable = new Hashtable<String, String>();
135         hashtable.put("name", name);
136         hashtable.put("url", url);
137         hashtable.put("path", strPath);
138         return hashtable;
139     }
140
141     public class DraggableDroppableTree extends JTree implements IDragonDropDataProvider
142     {
143         public DraggableDroppableTree(String startPath)
144         {
145             String url = "";
146             try {
147                 url = new File(startPath).toURI().toURL().toString();
148             } catch (Throwable cause) {
149                 logger.warn("failed to calculate URL for " + startPath);
150             }
151             setModel(new DefaultTreeModel(new DefaultMutableTreeNode(
152                     makeNode("top", url, startPath))));
153             setTransferHandler(new DragonTransferHandler(this));
154             setDragEnabled(true);
155         }
156
157         @Override
158         public boolean consumeDropList(List<Object> fileSet, Point location)
159         {
160             logger.debug("into consume dropped files, file set is:");
161             for (int i = 0; i < fileSet.size(); i++) {
162                 logger.debug("   " + ((File) fileSet.get(i)).getPath());
163             }
164             return true;
165         }
166
167         @Override
168         public List<Object> provideDragList()
169         {
170             ArrayList<Object> toReturn = new ArrayList<Object>();
171             TreePath tsp = getSelectionPath();
172             if (tsp == null)
173                 return toReturn;
174             logger.debug("got the path...");
175             Hashtable<String, String> table = NodeToTable(tsp.getLastPathComponent());
176             if (table != null) {
177                 toReturn.add(new File(table.get("path")));
178             }
179             return toReturn;
180         }
181
182         public void expandAll()
183         {
184             int row = 0;
185             while (row < getRowCount()) {
186                 expandRow(row);
187                 row++;
188             }
189         }
190
191     }
192
193     public class CustomCellRenderer implements TreeCellRenderer
194     {
195         DefaultTreeCellRenderer defRend = new DefaultTreeCellRenderer();
196
197         private String getValueString(Object value)
198         {
199             String returnString = "empty";
200             Hashtable<String, String> table = NodeToTable(value);
201             if (table != null) {
202                 returnString = table.get("name") + " -> " + table.get("url");
203             } else {
204                 returnString = "??: " + value.toString();
205             }
206             return returnString;
207         }
208
209         @Override
210         public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
211                 boolean expanded, boolean leaf, int row, boolean hasFocus)
212         {
213             defRend.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row,
214                     hasFocus);
215             defRend.setText(getValueString(value));
216             return defRend;
217         }
218     }
219
220     public static void main(String s[])
221     {
222         PropertyConfigurator.configure("log4j.properties");
223         // starting with user's personal area.
224         String homedir = System.getenv("HOME");
225         if ((homedir == null) || (homedir.length() == 0)) {
226             // fall back to the root if no home directory.
227             homedir = "/";
228         }
229         JFrame frame = new dragdrop_tree_test(homedir);
230         frame.addWindowListener(new WindowAdapter()
231         {
232             public void windowClosing(WindowEvent e)
233             {
234                 System.exit(0);
235             }
236         });
237         frame.pack();
238         frame.setVisible(true);
239     }
240
241 }