我创建了一个资源管理器,左边是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的功能呢?

解决方案 »

  1.   

    按我的理解,左边是文件目录的树结构,右边是树上选中的目录结构下的文件【可以是目录也可以是文件】,这一点在树上面设置TreeSelectionListener就可以。
    右边的表格中,没必要把第一列写上其详细目录,根据tree上选中的path拼接上table里的文件名就可以。给注册MouseListener,双击一行的话,获取当前行的文件详细目录,如果是文件夹,就在树上打开该文件夹目录,进而表格就显示刚才双击的目录下的文件;如果是文件,就试着用desktop类打开。
      

  2.   


    我现在用String name= fileSystemView.getSystemDisplayName(f);
    来获取表格的文件名,一旦它是根目录(显示为“本地目录 c:\”,而不是“c:\”),就不能正常显示,要没有根目录,光是文件夹就可已成功了=。=
      

  3.   

    比较?
    请问你左边的树和右边的Table是什么关系?
    他们如果有关联,我认为可以考虑共用同一个对象,比较缺失是一件比较麻烦的事情,有时,难免出纰漏。
    这部分信息你没有说,我无从得知。所以,你先考虑,如果有疑问,可以再补充这部分,在做探讨。
      

  4.   


    就是资源管理器啊,左边的tree点开一个文件夹,右面表里显示该文件夹目录下的文件
      

  5.   


    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;
    }
    }
    }
      

  6.   

    抱歉,写得比较仓促,有几个问题我就没有做。
    第一,有些文件是打不开的。可能会出异常。我没有处理。
    第二,逻辑上我不知道是不是有漏洞。如果你发现了,请你告诉我,提醒我。
    第三,写的实在太仓促,注释没有加,而且有些写法纯属个人风格。我现在基本明白你说打不开C,D,E盘的问题了。应该是你传递的不是File对象。所以你重新构建的时候,就不一样了。FileSystemView获取的显示名称~~这里用不上吧。
    例如C:\应的File对象,getName得到是空串。呵。你再体会下。发现什么问题可再交流。
      

  7.   


    万分感谢~~高人高人~~Orz!