我创建了一个资源管理器,左边是JTree,右边是Jtable
现在想实现如下功能,双击JTable的一行,可以展开文件夹,或者打开Txt文档有如下这么一个函数:
public void openSelect(){
try{
//obj 是表格选择文件的路径
Object obj=model.getValueAt(getSelectedRow(),0);
Object obj2=model.getValueAt(0,0); if(obj==null)return;
File f=(File)obj; String text=obj.toString();
TreePath p = tree.getLeadSelectionPath();
Object []path= p.getPath();//System.out.println("text is "+text);//System.out.println("treepath is "+tree.getSelectionPath().toString()); if(f.isDirectory()){
//tree expended
int index=tree.getRowForPath(p);
tree.expandRow(index);
while (!(tree.getLastSelectedPathComponent().toString().trim().equals(text)))
tree.setSelectionRow(index++);
tree.expandRow(index-1);
} else{
String postfix=text.toUpperCase();
System.out.println("postfix is "+postfix);
if(postfix.indexOf(".TXT")!=-1
//||postfix.indexOf(".JAVA")!=-1||postfix.indexOf(".HTM")!=-1||postfix.indexOf(".LOG")!=-1
) //exec("命令语句")
Runtime.getRuntime().exec("NotePad.exe "+text);
System.out.println("command is NotePad.exe "+text);
//open select file
}
}catch(Exception ee){}
}
红字的那一段是不对的,本来要表示Jtree的上一个结点的值和JTable当前选择的一个单元格的值作比较。
比如c:\windows\docs这个目录左面tree 的对应值是 windows,但右面表格的值本来应该是docs,这样如果他们equals,则可以用notebook打开txt文档,否则继续展开JTree。但是以model.getValueAt(getSelectedRow(),0)是一个路径,即“c:\windows\docs”,而不是docs,所以无法比较。如果用tree.getSelectionPath(),返回的是[c:\, windows],还是无法比较。
怎么能叫这两个东西比较,然后实现展开jtree的功能呢?
现在想实现如下功能,双击JTable的一行,可以展开文件夹,或者打开Txt文档有如下这么一个函数:
public void openSelect(){
try{
//obj 是表格选择文件的路径
Object obj=model.getValueAt(getSelectedRow(),0);
Object obj2=model.getValueAt(0,0); if(obj==null)return;
File f=(File)obj; String text=obj.toString();
TreePath p = tree.getLeadSelectionPath();
Object []path= p.getPath();//System.out.println("text is "+text);//System.out.println("treepath is "+tree.getSelectionPath().toString()); if(f.isDirectory()){
//tree expended
int index=tree.getRowForPath(p);
tree.expandRow(index);
while (!(tree.getLastSelectedPathComponent().toString().trim().equals(text)))
tree.setSelectionRow(index++);
tree.expandRow(index-1);
} else{
String postfix=text.toUpperCase();
System.out.println("postfix is "+postfix);
if(postfix.indexOf(".TXT")!=-1
//||postfix.indexOf(".JAVA")!=-1||postfix.indexOf(".HTM")!=-1||postfix.indexOf(".LOG")!=-1
) //exec("命令语句")
Runtime.getRuntime().exec("NotePad.exe "+text);
System.out.println("command is NotePad.exe "+text);
//open select file
}
}catch(Exception ee){}
}
红字的那一段是不对的,本来要表示Jtree的上一个结点的值和JTable当前选择的一个单元格的值作比较。
比如c:\windows\docs这个目录左面tree 的对应值是 windows,但右面表格的值本来应该是docs,这样如果他们equals,则可以用notebook打开txt文档,否则继续展开JTree。但是以model.getValueAt(getSelectedRow(),0)是一个路径,即“c:\windows\docs”,而不是docs,所以无法比较。如果用tree.getSelectionPath(),返回的是[c:\, windows],还是无法比较。
怎么能叫这两个东西比较,然后实现展开jtree的功能呢?
右边的表格中,没必要把第一列写上其详细目录,根据tree上选中的path拼接上table里的文件名就可以。给注册MouseListener,双击一行的话,获取当前行的文件详细目录,如果是文件夹,就在树上打开该文件夹目录,进而表格就显示刚才双击的目录下的文件;如果是文件,就试着用desktop类打开。
我现在用String name= fileSystemView.getSystemDisplayName(f);
来获取表格的文件名,一旦它是根目录(显示为“本地目录 c:\”,而不是“c:\”),就不能正常显示,要没有根目录,光是文件夹就可已成功了=。=
请问你左边的树和右边的Table是什么关系?
他们如果有关联,我认为可以考虑共用同一个对象,比较缺失是一件比较麻烦的事情,有时,难免出纰漏。
这部分信息你没有说,我无从得知。所以,你先考虑,如果有疑问,可以再补充这部分,在做探讨。
就是资源管理器啊,左边的tree点开一个文件夹,右面表里显示该文件夹目录下的文件
package h;import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;public class FileSystemDemo extends JFrame {
private static final long serialVersionUID = 1L;
private JTree tree;
private JTable table; private HashMap<File, List<File>> directoryMap;
private HashMap<File, List<File>> fileMap; private List<List<String>> tableData;
private final String[] COLUMN_NAMES = new String[] { "Name", "LastModify",
"Size" }; private File currSelFile = null; private TreeSelectionListener listener = new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
TreePath path = tree.getSelectionPath();
if (path == null) {
return;
} Object obj = path.getLastPathComponent();
if (obj instanceof File) {
File f = (File) obj;
currSelFile = f;
List<File> subFiles = Arrays.asList(f.listFiles());
if (subFiles == null || subFiles.size() == 0) {
return;
}
tableData.clear(); for (Iterator<File> it = subFiles.iterator(); it.hasNext();) {
File file = it.next();
List<String> record = new ArrayList<String>();
record.add(file.getName().length() == 0 ? file
.getAbsolutePath() : file.getName());
record.add(String.valueOf(file.lastModified()));
record.add(String.valueOf(file.getTotalSpace()));
tableData.add(record);
}
((DefaultTableModel) table.getModel()).fireTableDataChanged();
}
}
}; public FileSystemDemo() {
super(); directoryMap = new HashMap<File, List<File>>();
fileMap = new HashMap<File, List<File>>();
tableData = new ArrayList<List<String>>(); init();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
setVisible(true);
} private void init() {
Container c = getContentPane();
c.setLayout(new BorderLayout());
JSplitPane jsp = new JSplitPane();
tree = new JTree();
tree.addTreeSelectionListener(listener);
tree.setCellRenderer(new FileTreeCellRenderer());
tree.setModel(new FileTreeModel()); jsp.setLeftComponent(new JScrollPane(tree)); table = new JTable();
table.setModel(new FileTableModel());
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1
&& e.getClickCount() >= 2) {
if (currSelFile != null) {
List<File> files = Arrays.asList(currSelFile
.listFiles());
int index = table.getSelectedRow();
if (index < 0) {
return;
}
File f = files.get(index);
openFile(f);
}
}
} });
jsp.setRightComponent(new JScrollPane(table)); jsp.setDividerLocation(300);
c.add(jsp, BorderLayout.CENTER);
} private void openFile(File f) {
Desktop d = Desktop.getDesktop();
try {
d.open(f); } catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
new FileSystemDemo();
} private List<File> getDirectory(File f) {
List<File> subDirectory;
if (!directoryMap.containsKey(f)) {
subDirectory = new ArrayList<File>();
File[] listFiles = f.listFiles();
for (int i = 0; i < listFiles.length; i++) {
File file = listFiles[i];
if (file.isDirectory()) {
subDirectory.add(file);
}
} directoryMap.put(f, subDirectory);
} else {
subDirectory = directoryMap.get(f);
} return subDirectory;
} private List<File> getFiles(File f) {
List<File> subFiles; if (!fileMap.containsKey(f)) {
subFiles = new ArrayList<File>();
File[] listFiles = f.listFiles();
for (int i = 0; i < listFiles.length; i++) {
File file = listFiles[i];
if (file.isFile()) {
subFiles.add(file);
}
} fileMap.put(f, subFiles);
} else {
subFiles = fileMap.get(f);
}
return subFiles;
} private class FileTreeModel extends DefaultTreeModel { private static final long serialVersionUID = 1L; public FileTreeModel() {
super(null);
} @Override
public Object getRoot() {
return FileSystemView.getFileSystemView().getRoots()[0];
} @Override
public int getChildCount(Object parent) {
int rs = 0;
if (parent instanceof File) {
rs = getDirectory((File) parent).size();
}
return rs;
} @Override
public Object getChild(Object parent, int index) {
Object obj = null;
if (parent instanceof File) {
File f = (File) parent;
List<File> subDiretory = getDirectory(f);
File file = subDiretory.get(index);
obj = file;
} return obj;
} @Override
public boolean isLeaf(Object node) {
boolean rs = true; if (node instanceof File) {
File f = (File) node;
List<File> directory = getDirectory(f);
rs = directory == null || directory.size() == 0;
} return rs;
} } private class FileTreeCellRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 1L; @Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component treeCellRendererComponent = super
.getTreeCellRendererComponent(tree, value, sel, expanded,
leaf, row, hasFocus);
if (value instanceof File) {
File f = (File) value;
setIcon(FileSystemView.getFileSystemView().getSystemIcon(f));
String name = f.toString();
if (name.endsWith(File.separator)) {
name = name.substring(0, name.length() - 1);
} else {
int index = name.lastIndexOf(File.separator);
name = name.substring(index + 1, name.length());
} setText(name);
} return treeCellRendererComponent;
}
} private class FileTableModel extends DefaultTableModel { private static final long serialVersionUID = 1L; @Override
public int getRowCount() {
return tableData.size();
} @Override
public int getColumnCount() {
return COLUMN_NAMES.length;
} @Override
public String getColumnName(int column) {
return COLUMN_NAMES[column];
} @Override
public Object getValueAt(int row, int column) {
return tableData.get(row).get(column);
} @Override
public boolean isCellEditable(int row, int column) {
return false;
}
}
}
第一,有些文件是打不开的。可能会出异常。我没有处理。
第二,逻辑上我不知道是不是有漏洞。如果你发现了,请你告诉我,提醒我。
第三,写的实在太仓促,注释没有加,而且有些写法纯属个人风格。我现在基本明白你说打不开C,D,E盘的问题了。应该是你传递的不是File对象。所以你重新构建的时候,就不一样了。FileSystemView获取的显示名称~~这里用不上吧。
例如C:\应的File对象,getName得到是空串。呵。你再体会下。发现什么问题可再交流。
万分感谢~~高人高人~~Orz!