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