2009-03-15 4 views
0

파일 시스템의 디렉토리에 대한 JTree 구현이 있습니다. 내가 가지고있는 문제는 디렉토리가 제거되거나 이름이 바뀌었을 때 트리가 여전히 디렉토리를 부모에 표시한다는 것입니다. 노드가 확장되면 상위 트리가 변경 사항에 대해 업데이트되지 않는 것처럼 보입니다.(파일 시스템 트리에서) JTree 캐싱 노드를 중지 할 수 있습니까?

필자가 작성한 모델은 캐시되지 않습니다 (필자는 제한된 캐싱에 대해 주석을 달았습니다). JTree 자체가 노드를 캐싱 한 것과 같습니다.

코드 (모델이 중첩 된 서브 클래스) :

public class FileSystemTree 
extends JTree 
{ 

// ***************************************************************************** 
// INSTANCE CREATE/DELETE 
// ***************************************************************************** 

public FileSystemTree() { 
    this(new Model(null,null,null)); 
    } 

public FileSystemTree(String startPath) { 
    this(new Model(startPath,null,null)); 
    } 

public FileSystemTree(FileSelector inc, FileSelector exc) { 
    this(new Model(null,inc,exc)); 
    } 

public FileSystemTree(String startPath, FileSelector inc, FileSelector exc) { 
    this(new Model(startPath,inc,exc)); 
    } 

private FileSystemTree(Model model) { 
    super(model); 

    //setLargeModel(true); 
    setRootVisible(false); 
    setShowsRootHandles(true); 
    putClientProperty("JTree.lineStyle","Angled"); 
    } 

// ***************************************************************************** 
// INSTANCE METHODS - ACCESSORS 
// ***************************************************************************** 

public Object getRoot() { 
    return getModel().getRoot(); 
    } 

// ***************************************************************************** 
// INSTANCE METHODS 
// ***************************************************************************** 

public String convertValueToText(Object value,boolean selected,boolean expanded,boolean leaf,int row,boolean hasFocus) { 
    File        fil=(File)value; 

    return (fil.getName().length()!=0 ? fil.getName() : fil.getPath()); 
    } 

// ***************************************************************************** 
// STATIC NESTED CLASSES - SUPPORTING MODEL 
// ***************************************************************************** 

    static class Model 
    extends Object 
    implements TreeModel, FilenameFilter 
    { 

    private File      root;         // tree root 
    //ivate Map       cache;         // caches child counts for directories 
    private File[]      fsRoots;        // copy of file system roots 
    private FileSelector    include;        // inclusion selector 
    private FileSelector    exclude;        // exclusion selector 
    private java.util.List    listeners=new ArrayList(); 

    public Model(String roo, FileSelector inc, FileSelector exc) { 
     super(); 

     root=(roo==null ? DRIVES : new File(roo)); 
     //cache=new HashMap(); 
     fsRoots=(root==DRIVES ? rootList() : null); 
     include=inc; 
     exclude=exc; 
     } 

    // ***************************************************************************** 
    // METHODS - MODEL 
    // ***************************************************************************** 

    public Object getRoot() { 
     return root; 
     } 

    public Object getChild(Object parent, int index) { 
     File       dir=(File)parent; 

     if(dir==DRIVES) { 
      File[] chl=fsRoots; //rootList(); 
      return (index<chl.length ? chl[index] : null); 
      } 
     else { 
      String[] chl=dirList(dir); 
      return (index<chl.length ? new File(dir,chl[index]) : null); 
      } 
     } 

    public int getChildCount(Object parent) { 
     File       dir=(File)parent; 
     //Integer       cch=(Integer)cache.get(dir); 

     //if(cch!=null) { 
     // return cch.intValue(); 
     // } 

     if(dir==DRIVES) { 
      return fsRoots.length; //rootList().length; 
      } 
     else if(dir.isDirectory()) { 
      return dirList(dir).length; 
      } 
     else { 
      return 0; 
      } 
     } 

    public boolean isLeaf(Object node) { 
     return((File)node).isFile(); 
     } 

    public void valueForPathChanged(TreePath path, Object newValue) { 
     } 

    public int getIndexOfChild(Object parent, Object child) { 
     File       dir=(File)parent; 
     File       fse=(File)child; 

     if(dir==DRIVES) { 
      File[] ca=fsRoots; //rootList(); 
      for(int xa=0; xa<ca.length; xa++) { 
       if(fse.equals(ca[xa])) { return xa; } 
       } 
      } 
     else { 
      String[] ca=dirList(dir); 
      for(int xa=0; xa<ca.length; ++xa) { 
       if(fse.getName().equals(ca[xa])) { return xa; } 
       } 
      } 
     return -1; 
     } 

    private File[] rootList() { 
     File[]       lst=File.listRoots(); 

     if(lst==null) { lst=new File[0]; } 
     //cache.put(DRIVES,new Integer(lst.length)); 
     return lst; 
     } 

    private String[] dirList(File dir) { 
     String[]      lst=dir.list(this); 

     if(lst==null) { lst=new String[0]; } 
     //cache.put(dir,new Integer(lst.length)); 
     return lst; 
     } 

    // ***************************************************************************** 
    // METHODS - FILENAME FILTER 
    // ***************************************************************************** 

    public boolean accept(File dir, String nam) { 
     return ((include==null || include.accept(dir,nam)) && (exclude==null || !exclude.accept(dir,nam))); 
     } 

    // ***************************************************************************** 
    // METHODS - LISTENER 
    // ***************************************************************************** 

    public void addTreeModelListener(TreeModelListener listener) { 
     if(listener != null && !listeners.contains(listener)) { 
      listeners.add(listener); 
      } 
     } 

    public void removeTreeModelListener(TreeModelListener listener) { 
     if(listener != null) { 
      listeners.remove(listener); 
      } 
     } 

    public void fireTreeNodesChanged(TreeModelEvent evt) { 
     Iterator      itr=listeners.iterator(); 

     while(itr.hasNext()) { 
      TreeModelListener listener=(TreeModelListener)itr.next(); 
      listener.treeNodesChanged(evt); 
      } 
     } 

    public void fireTreeNodesInserted(TreeModelEvent evt) { 
     Iterator      itr=listeners.iterator(); 

     while(itr.hasNext()) { 
      TreeModelListener listener=(TreeModelListener)itr.next(); 
      listener.treeNodesInserted(evt); 
      } 
     } 

    public void fireTreeNodesRemoved(TreeModelEvent evt) { 
     Iterator      itr=listeners.iterator(); 

     while(itr.hasNext()) { 
      TreeModelListener listener=(TreeModelListener)itr.next(); 
      listener.treeNodesRemoved(evt); 
      } 
     } 

    public void fireTreeStructureChanged(TreeModelEvent evt) { 
     Iterator      itr=listeners.iterator(); 

     while(itr.hasNext()) { 
      TreeModelListener listener=(TreeModelListener)itr.next(); 
      listener.treeStructureChanged(evt); 
      } 
     } 
    } // END INNER CLASS 

// ***************************************************************************** 
// STATIC PROPERTIES 
// ***************************************************************************** 

static private final File    DRIVES=new File("*DRIVES");    // marker for listing file system drives 

} // END PUBLIC CLASS 

답변

2

모델은 청취자에게 트리 구조의 수정 사항을 알리는 역할을합니다. 트리는 이러한 통지가 없을 경우 자체를 새로 고치지 않습니다.

+0

나는 나무가 기능하는 방식을 오해하고 있었다. 파일 시스템의 변경 사항을 알리기 위해 모델을 사용해야한다는 것을 알지 못했습니다. 내 경우에는 무엇이 바뀌 었는지 정확히 알기 때문에 트리 모델 이벤트를 실행하는 것은 간단했다. –

0

당신은 파일 시스템의 변화를 보이는 몇 가지 배경 스레드를 작성하고이 디렉토리가 변경되었음을 감지 할 경우 일부 모델 변경 이벤트를 발생 할 수있다.

0

모델 코드를 보지 않고 getChild 메소드와 같이 호출 중인지 확인하십시오.

+0

@TofuBeer : 코드가 질문에 게시됩니다. JTree 하위 클래스의 중첩 클래스입니다. –

+0

죄송합니다. 놓치 셨을 것입니다. – TofuBeer