【发布时间】:2018-08-10 09:47:03
【问题描述】:
我想创建一个应用程序,它将显示目录中的文件,其名称以字符串开头,即某个日期。现在我可以显式地使用所有 FileNameFilter 但由于 TreeModel 是一个接口,我无法更改任何内容。在函数getChild(Object parent , int index) 我得到 ArrayOutofBoundException 因为当我访问它时数组变空,因为过滤器从列表中删除了文件名。我被困在这里没有可能的解决方案。我尝试了更多的东西。
我在这里使用摆动轮廓。
调用 TreeModel 的代码:
FileTreeModel treeMdl = new FileTreeModel(f);
treeMdl.setDate(strDate);
mdl = DefaultOutlineModel.createOutlineModel(treeMdl, new FileRowModel(), true);
outline.setRenderDataProvider(new RenderData());
outline.setModel(mdl);
类文件树模型:
public class FileTreeModel implements TreeModel {
private String date;
private File root;
public FileTreeModel(File root) {
this.root = root;
}
@Override
public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
}
@Override
public Object getChild(Object parent, int index) {
File f = (File) parent;
File[] listFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().startsWith(date);
}
});
return listFiles[index];
}
public void setDate(String Date) {
date = Date;
}
public Object getChild1(Object parent, int index, String dir, String date) throws IOException {
File f = (File) parent;
File[] listFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().startsWith(date);
}
});
return listFiles[index].getName();
}
@Override
public int getChildCount(Object parent) {
File f = (File) parent;
if (!f.isDirectory()) {
return 0;
} else {
return f.list().length;
}
}
@Override
public int getIndexOfChild(Object parent, Object child) {
File par = (File) parent;
File ch = (File) child;
return Arrays.asList(par.listFiles()).indexOf(ch);
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
File f = (File) node;
return !f.isDirectory();
}
@Override
public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
}
@Override
public void valueForPathChanged(javax.swing.tree.TreePath path, Object newValue) {
//do nothing
}
}
在这里我还创建了一个函数getChild1(),它可以正确地返回我想要的文件列表,但由于无法控制索引参数,我无法在接口中获得相同的结果。
编辑:
输出:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2
at sr.view.FileTreeModel.getChild(FileTreeModel.java:57)
at org.netbeans.swing.outline.DefaultOutlineModel.getChild(DefaultOutlineModel.java:231)
at javax.swing.tree.FixedHeightLayoutCache$SearchInfo.getPath(FixedHeightLayoutCache.java:1467)
at javax.swing.tree.FixedHeightLayoutCache.getPathForRow(FixedHeightLayoutCache.java:211)
at org.netbeans.swing.outline.Outline.sortAndFilter(Outline.java:511)
at org.netbeans.swing.etable.ETable.convertRowIndexToModel(ETable.java:1599)
at javax.swing.JTable.getValueAt(JTable.java:2719)
at org.netbeans.swing.etable.ETable.getValueAt(ETable.java:772)
【问题讨论】:
-
在您的
getChild1()中,您没有使用参数dir,并且您已经在模型中找到了日期。那么与getChild()有什么区别呢?除此之外,您可能需要考虑将文件包装在代表节点的某个类中,并使用toString()显示文件名,或者为您的节点使用自定义渲染器。 -
@Thomas
getChild()是摆动轮廓模型使用的函数,因为它是一个接口。getChild1()只是为了测试目的而创建的,它是成功的。但我无法在getChild()中实现过滤器。 -
如需尽快获得更好的帮助,请发帖minimal reproducible example 或Short, Self Contained, Correct Example。
-
我的问题是:像您实施
getChild1()那样实施getChild()有什么问题?正如我所说,不同的签名应该不是问题,因为无论如何您都不使用dir,并且可以从模型本身获得date。剩下的是与getChild()完全相同的签名(除了 throws 声明,但这可以通过将异常包装在RuntimeException中来解决)。 -
您的 getChildCOunt() 方法返回目录中的文件总数。但是您的 getChild() 方法会过滤文件列表。你需要保持一致。您的树要么显示所有文件,并且所有方法都应处理完整的文件列表,要么显示过滤列表,并且所有方法都应处理过滤列表。