做东西的时候需要实现资源管理器树形目录。正好在网上搜到这么个源代码,当边用边学习了 :)
1
import java.awt.*;
2
import java.awt.event.*;
3
import java.io.*;
4
import java.util.*;
5
6
import javax.swing.*;
7
import javax.swing.tree.*;
8
import javax.swing.event.*;
9
10
public class FileTree1
11
extends JFrame
12

{
13
public static final ImageIcon ICON_COMPUTER =
14
new ImageIcon("computer.gif");
15
public static final ImageIcon ICON_DISK =
16
new ImageIcon("disk.gif");
17
public static final ImageIcon ICON_FOLDER =
18
new ImageIcon("folder.gif");
19
public static final ImageIcon ICON_EXPANDEDFOLDER =
20
new ImageIcon("expandedfolder.gif");
21
22
protected JTree m_tree;
23
protected DefaultTreeModel m_model;
24
protected JTextField m_display;
25
26
public FileTree1()
27
{
28
super("Directories Tree");
29
setSize(400, 300);
30
31
DefaultMutableTreeNode top = new DefaultMutableTreeNode(
32
new IconData(ICON_COMPUTER, null, "Computer"));
33
34
DefaultMutableTreeNode node;
35
File[] roots = File.listRoots();
36
for (int k=0; k<roots.length; k++)
37
{
38
node = new DefaultMutableTreeNode(new IconData(ICON_DISK,
39
null, new FileNode(roots[k])));
40
top.add(node);
41
node.add( new DefaultMutableTreeNode(new Boolean(true)));
42
}
43
44
m_model = new DefaultTreeModel(top);
45
m_tree = new JTree(m_model);
46
m_tree.putClientProperty("JTree.lineStyle", "Angled");
47
48
TreeCellRenderer renderer = new
49
IconCellRenderer();
50
m_tree.setCellRenderer(renderer);
51
52
m_tree.addTreeExpansionListener(new
53
DirExpansionListener());
54
55
m_tree.addTreeSelectionListener(new
56
DirSelectionListener());
57
58
m_tree.getSelectionModel().setSelectionMode(
59
TreeSelectionModel.SINGLE_TREE_SELECTION);
60
m_tree.setShowsRootHandles(true);
61
m_tree.setEditable(false);
62
63
JScrollPane s = new JScrollPane();
64
s.getViewport().add(m_tree);
65
getContentPane().add(s, BorderLayout.CENTER);
66
67
m_display = new JTextField();
68
m_display.setEditable(false);
69
getContentPane().add(m_display, BorderLayout.NORTH);
70
71
WindowListener wndCloser = new WindowAdapter()
72
{
73
public void windowClosing(WindowEvent e)
74
{
75
System.exit(0);
76
}
77
};
78
addWindowListener(wndCloser);
79
80
setVisible(true);
81
}
82
83
DefaultMutableTreeNode getTreeNode(TreePath path)
84
{
85
return (DefaultMutableTreeNode)(path.getLastPathComponent());
86
}
87
88
FileNode getFileNode(DefaultMutableTreeNode node)
89
{
90
if (node == null)
91
return null;
92
Object obj = node.getUserObject();
93
if (obj instanceof IconData)
94
obj = ((IconData)obj).getObject();
95
if (obj instanceof FileNode)
96
return (FileNode)obj;
97
else
98
return null;
99
}
100
101
// Make sure expansion is threaded and updating the tree model
102
// only occurs within the event dispatching thread.
103
class DirExpansionListener implements TreeExpansionListener
104
{
105
public void treeExpanded(TreeExpansionEvent event)
106
{
107
final DefaultMutableTreeNode node = getTreeNode(
108
event.getPath());
109
final FileNode fnode = getFileNode(node);
110
111
Thread runner = new Thread()
112
{
113
public void run()
114
{
115
if (fnode != null && fnode.expand(node))
116
{
117
Runnable runnable = new Runnable()
118
{
119
public void run()
120
{
121
m_model.reload(node);
122
}
123
};
124
SwingUtilities.invokeLater(runnable);
125
}
126
}
127
};
128
runner.start();
129
}
130
131
public void treeCollapsed(TreeExpansionEvent event)
{}
132
}
133
134
135
class DirSelectionListener
136
implements TreeSelectionListener
137
{
138
public void valueChanged(TreeSelectionEvent event)
139
{
140
DefaultMutableTreeNode node = getTreeNode(
141
event.getPath());
142
FileNode fnode = getFileNode(node);
143
if (fnode != null)
144
m_display.setText(fnode.getFile().
145
getAbsolutePath());
146
else
147
m_display.setText("");
148
}
149
}
150
151
public static void main(String argv[])
152
{
153
new FileTree1();
154
}
155
}
156
157
class IconCellRenderer
158
extends JLabel
159
implements TreeCellRenderer
160

{
161
protected Color m_textSelectionColor;
162
protected Color m_textNonSelectionColor;
163
protected Color m_bkSelectionColor;
164
protected Color m_bkNonSelectionColor;
165
protected Color m_borderSelectionColor;
166
167
protected boolean m_selected;
168
169
public IconCellRenderer()
170
{
171
super();
172
m_textSelectionColor = UIManager.getColor(
173
"Tree.selectionForeground");
174
m_textNonSelectionColor = UIManager.getColor(
175
"Tree.textForeground");
176
m_bkSelectionColor = UIManager.getColor(
177
"Tree.selectionBackground");
178
m_bkNonSelectionColor = UIManager.getColor(
179
"Tree.textBackground");
180
m_borderSelectionColor = UIManager.getColor(
181
"Tree.selectionBorderColor");
182
setOpaque(false);
183
}
184
185
public Component getTreeCellRendererComponent(JTree tree,
186
Object value, boolean sel, boolean expanded, boolean leaf,
187
int row, boolean hasFocus)
188
189
{
190
DefaultMutableTreeNode node =
191
(DefaultMutableTreeNode)value;
192
Object obj = node.getUserObject();
193
setText(obj.toString());
194
195
if (obj instanceof Boolean)
196
setText("Retrieving data
");
197
198
if (obj instanceof IconData)
199
{
200
IconData idata = (IconData)obj;
201
if (expanded)
202
setIcon(idata.getExpandedIcon());
203
else
204
setIcon(idata.getIcon());
205
}
206
else
207
setIcon(null);
208
209
setFont(tree.getFont());
210
setForeground(sel ? m_textSelectionColor :
211
m_textNonSelectionColor);
212
setBackground(sel ? m_bkSelectionColor :
213
m_bkNonSelectionColor);
214
m_selected = sel;
215
return this;
216
}
217
218
219
public void paintComponent(Graphics g)
220
{
221
Color bColor = getBackground();
222
Icon icon = getIcon();
223
224
g.setColor(bColor);
225
int offset = 0;
226
if(icon != null && getText() != null)
227
offset = (icon.getIconWidth() + getIconTextGap());
228
g.fillRect(offset, 0, getWidth() - 1 - offset,
229
getHeight() - 1);
230
231
if (m_selected)
232
{
233
g.setColor(m_borderSelectionColor);
234
g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
235
}
236
super.paintComponent(g);
237
}
238
}
239
240
class IconData
241

{
242
protected Icon m_icon;
243
protected Icon m_expandedIcon;
244
protected Object m_data;
245
246
public IconData(Icon icon, Object data)
247
{
248
m_icon = icon;
249
m_expandedIcon = null;
250
m_data = data;
251
}
252
253
public IconData(Icon icon, Icon expandedIcon, Object data)
254
{
255
m_icon = icon;
256
m_expandedIcon = expandedIcon;
257
m_data = data;
258
}
259
260
public Icon getIcon()
261
{
262
return m_icon;
263
}
264
265
public Icon getExpandedIcon()
266
{
267
return m_expandedIcon!=null ? m_expandedIcon : m_icon;
268
}
269
270
public Object getObject()
271
{
272
return m_data;
273
}
274
275
public String toString()
276
{
277
return m_data.toString();
278
}
279
}
280
281
class FileNode
282

{
283
protected File m_file;
284
285
public FileNode(File file)
286
{
287
m_file = file;
288
}
289
290
public File getFile()
291
{
292
return m_file;
293
}
294
295
public String toString()
296
{
297
return m_file.getName().length() > 0 ? m_file.getName() :
298
m_file.getPath();
299
}
300
301
public boolean expand(DefaultMutableTreeNode parent)
302
{
303
DefaultMutableTreeNode flag =
304
(DefaultMutableTreeNode)parent.getFirstChild();
305
if (flag==null) // No flag
306
return false;
307
Object obj = flag.getUserObject();
308
if (!(obj instanceof Boolean))
309
return false; // Already expanded
310
311
parent.removeAllChildren(); // Remove Flag
312
313
File[] files = listFiles();
314
if (files == null)
315
return true;
316
317
Vector v = new Vector();
318
319
for (int k=0; k<files.length; k++)
320
{
321
File f = files[k];
322
if (!(f.isDirectory()))
323
continue;
324
325
FileNode newNode = new FileNode(f);
326
327
boolean isAdded = false;
328
for (int i=0; i<v.size(); i++)
329
{
330
FileNode nd = (FileNode)v.elementAt(i);
331
if (newNode.compareTo(nd) < 0)
332
{
333
v.insertElementAt(newNode, i);
334
isAdded = true;
335
break;
336
}
337
}
338
if (!isAdded)
339
v.addElement(newNode);
340
}
341
342
for (int i=0; i<v.size(); i++)
343
{
344
FileNode nd = (FileNode)v.elementAt(i);
345
IconData idata = new IconData(FileTree1.ICON_FOLDER,
346
FileTree1.ICON_EXPANDEDFOLDER, nd);
347
DefaultMutableTreeNode node = new
348
DefaultMutableTreeNode(idata);
349
parent.add(node);
350
351
if (nd.hasSubDirs())
352
node.add(new DefaultMutableTreeNode(
353
new Boolean(true) ));
354
}
355
356
return true;
357
}
358
359
public boolean hasSubDirs()
360
{
361
File[] files = listFiles();
362
if (files == null)
363
return false;
364
for (int k=0; k<files.length; k++)
365
{
366
if (files[k].isDirectory())
367
return true;
368
}
369
return false;
370
}
371
372
public int compareTo(FileNode toCompare)
373
{
374
return m_file.getName().compareToIgnoreCase(
375
toCompare.m_file.getName() );
376
}
377
378
protected File[] listFiles()
379
{
380
if (!m_file.isDirectory())
381
return null;
382
try
383
{
384
return m_file.listFiles();
385
}
386
catch (Exception ex)
387
{
388
JOptionPane.showMessageDialog(null,
389
"Error reading directory "+m_file.getAbsolutePath(),
390
"Warning", JOptionPane.WARNING_MESSAGE);
391
return null;
392
}
393
}
394
}
395
396