2016-01-30 14 views
1

Изучая компонент JTree, я написал небольшой класс, в котором будут перечислены каталоги и файлы моего жесткого диска. Чтобы избежать «полной проверки», которая длилась бы длинные минуты и была бы пустой тратой времени и ресурсов, я решил, что я исследую только один уровень уровня «активный узел». Под «активным узлом», я имею в виду, что каталог щелкнул ИЛИ узел расширился.JTree: Почему мой каталог не отображается как каталог?

Для каталога нажмите, он отлично работает: я могу исследовать мои каталоги и подкаталоги, код работает «под-уровень на суб-уровне», а выбранные каталоги отображаются как каталоги.

Но если я разворачиваю узел, это терпит неудачу! Метод изучения детей этих узлов работает; он находит всех детей и может их перечислить через «System.out.println (...)», но мои каталоги по-прежнему отображаются как файлы, даже если у них есть дети. Чтобы каталог выглядел как каталог, я должен нажать на него (= использовать «первый метод»).

Вот мой код. Кто-нибудь может объяснить мне, что не удается?

import java.awt.BorderLayout; 
import java.io.File; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.event.TreeExpansionEvent; 
import javax.swing.event.TreeExpansionListener; 
import javax.swing.event.TreeSelectionEvent; 
import javax.swing.event.TreeSelectionListener; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.TreePath; 

public class Explorer2 extends JPanel { 
private JTree tree; 
private DefaultMutableTreeNode root= new DefaultMutableTreeNode(); 
int countSubLevel=0; 
int limit=1; 

Explorer2() { 
    DefaultMutableTreeNode driveNode=null; 
    for (File file:File.listRoots()) { 
     driveNode = new DefaultMutableTreeNode(file.getAbsolutePath()); 
     //testLeaf(driveNode);   
     exploreDirectory(file, driveNode); 
     root.add(driveNode); 
    } 

    displayTree(); 
} 

Explorer2(String rootDirectory) { 
    File file = new File(rootDirectory); 
    DefaultMutableTreeNode directoryNode = new DefaultMutableTreeNode(file.getAbsolutePath()); 
    exploreDirectory(file, directoryNode); 
    root.add(directoryNode); 
    displayTree(); 
} 

public void exploreDirectory (File dir, DefaultMutableTreeNode dirNode) { 
    if (dir.isDirectory()) { 
     //System.out.println(dir+" (parent) is a directory. Its level is : "+dirNode.getLevel()); 
     try { 
      for (File file:dir.listFiles()) { 
       DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(file.getAbsolutePath()); 

       dirNode.add(fileNode); 
       //System.out.println(dirNode+" - "+file+" - Level = "+fileNode.getLevel()); 
       /* 
       if (fileNode.getLevel()<limit) { 
        System.out.println(file+" (child) have a level : "+fileNode.getLevel()); 
        exploreDirectory(file, fileNode); 
       } else { 
        //System.out.println("Not in the loop : "+fileNode.getLevel()); 
       } 
       */ 

      } 

     } catch (NullPointerException e) { 
      System.err.println(dir+" generates a NullPointerException"); 
     }   

    } else { 
     System.out.println(dir+" is a file. Its level is : "+dirNode.getLevel()); 
    } 
    countSubLevel+=1; 
} 

public void displayTree() { 
    DefaultTreeModel treeModel = new DefaultTreeModel(root); 
    tree = new JTree(treeModel); 
    //tree = new JTree(root); 
    tree.setRootVisible(true); 
    tree.addTreeSelectionListener(new MyTreeSelectionListener()); 
    tree.addTreeExpansionListener(new MyTreeExpansionListener()); 


    this.setLayout(new BorderLayout()); 
    this.add(new JScrollPane(tree), BorderLayout.CENTER); 
} 

public void testLeaf(DefaultMutableTreeNode dir) { 
    if (dir.isLeaf()) { 
     System.out.println("Rien en dessous de "+dir); 
    } else { 
     System.out.println("Creuse !"); 
    } 
} 

class MyTreeSelectionListener implements TreeSelectionListener { 
    @Override 
    public void valueChanged(TreeSelectionEvent arg0) { 
     if (tree.getLastSelectedPathComponent() != null) { 
      File dir = new File(tree.getLastSelectedPathComponent().toString()); 
      DefaultMutableTreeNode dirNode = (DefaultMutableTreeNode) arg0.getPath().getLastPathComponent(); 
      DefaultMutableTreeNode fileNode=null; 
      //System.out.println(dirNode.getChildCount()); 
      if (dirNode.getChildCount()==0) { 
       System.out.println("The directory is : "+dir+" - Node : "+dirNode); 
       exploreDirectory(dir, dirNode); 
      } 
     } 

    } 

} 

class MyTreeExpansionListener implements TreeExpansionListener { 

    @Override 
    public void treeCollapsed(TreeExpansionEvent arg0) { 
     System.out.println("Collapsed : "+arg0.getPath().getLastPathComponent()); 
    } 

    @Override 
    public void treeExpanded(TreeExpansionEvent arg0) { 
     DefaultMutableTreeNode dir = (DefaultMutableTreeNode) arg0.getPath().getLastPathComponent(); 
     DefaultMutableTreeNode fileNode=null; 
     System.out.println("Expanded directory is : "+dir+" - Number of child : "+dir.getChildCount());   
     for (int i=0 ; i<dir.getChildCount() ; i++) { 

      File file = new File(dir.getChildAt(i).toString()); 
      fileNode = new DefaultMutableTreeNode(file.getAbsolutePath()); 
      exploreDirectory(file, fileNode); 
      System.out.println("*"+i+" - directory is : "+dir+" - Files are : "+file+" - Number of children : "+fileNode.getChildCount()); 
     }   
    }  
} 

public static void main(String[] args) { 
    JFrame window = new JFrame(); 
    window.setSize(500, 600); 
    window.setTitle("Explorateur"); 
    window.setLocationRelativeTo(null); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setLayout(new BorderLayout()); 
    String str = System.getProperty("user.home"); 
    //Explorer2 explorer = new Explorer2(str); 
    Explorer2 explorer = new Explorer2(); 

    window.getContentPane().add(explorer); 
    window.setVisible(true); 

} 

} 

Благодаря всем ответам. С уважением.

ответ

1

Для использования в качестве модели для узлов в дереве вам необходимо использовать класс TreeModel, такой как DefaultTreeModel. У этого есть методы для системы, чтобы определить, является ли данный узел листом или нет, и разрешить любому узлу содержать детей или (как в вашем случае) только определенные узлы могут содержать детей.

Ваша программа не использует собственную модель, поэтому JTree просто создает свою собственную; так как нет способа создать модель для определения того, является ли узел листом или нет, если он не расширен, тогда он не знает, что это родительский узел с дочерними элементами до тех пор, пока он не будет расширен, а слушатель добавит к нему узлы.

+0

Хорошо, я добавил DefaultTreeModel, но ... ничего лучше ... –

+0

Вы используете DefaultTreeModel с DefaultMutableTreeNodes, они не могут знать, является ли данный узел поддеревом или листом. Расширьте DefaultMutableTreeNode и поместите ссылку на объект File в узле eadh или поместите объект File в setUserObject в каждый экземпляр DefaultMutableTreeNode. Затем переопределите isLeaf в расширении DefaultTreeModel и изучите свой файловый объект в данном узле, чтобы определить, есть ли у него дети. Swing вызовет это, чтобы определить, как отображать узел. – arcy