触发器是最近的re-detected SwingX issue:深度支持 - 在折叠节点下,而不是仅与可见节点相关,这是当前行为 - 节点搜索。
“Nichts leichter als das”我目前接触到SwingWorker:在后台线程中运行TreeModel并更新过程中的ui,如下面的原始片段所示。 Fest的EDT检查器很开心,但之后它只检查重绘(这在EDT很好地发生在这里)
仅严格来说,后台线程必须是EDT,因为它正在访问(通过读取)模型。所以,问题是:
特殊情况解决方案的一种可能性是使用第二个(克隆的或其他“相同”制作的)模型进行搜索,然后在“真实”模型中找到相应的匹配。对于一般的搜索支持,这并不能很好地发挥作用,因为它无法知道任何特定模型,即使它想要也无法创建克隆。另外,它必须应用所有视图排序/过滤(将来)......
// a crude worker (match hard-coded and directly coupled to the ui)
public static class SearchWorker extends SwingWorker<Void, File> {
private Enumeration enumer;
private JXList list;
private JXTree tree;
public SearchWorker(Enumeration enumer, JXList list, JXTree tree) {
this.enumer = enumer;
this.list = list;
this.tree = tree;
}
@Override
protected Void doInBackground() throws Exception {
int count = 0;
while (enumer.hasMoreElements()) {
count++;
File file = (File) enumer.nextElement();
if (match(file)) {
publish(file);
}
if (count > 100){
count = 0;
Thread.sleep(50);
}
}
return null;
}
@Override
protected void process(List<File> chunks) {
for (File file : chunks) {
((DefaultListModel) list.getModel()).addElement(file);
TreePath path = createPathToRoot(file);
tree.addSelectionPath(path);
tree.scrollPathToVisible(path);
}
}
private TreePath createPathToRoot(File file) {
boolean result = false;
List<File> path = new LinkedList<File>();
while(!result && file != null) {
result = file.equals(tree.getModel().getRoot());
path.add(0, file);
file = file.getParentFile();
}
return new TreePath(path.toArray());
}
private boolean match(File file) {
return file.getName().startsWith("c");
}
}
// its usage in terms of SwingX test support
public void interactiveDeepSearch() {
final FileSystemModel files = new FileSystemModel(new File("."));
final JXTree tree = new JXTree(files);
tree.setCellRenderer(new DefaultTreeRenderer(IconValues.FILE_ICON, StringValues.FILE_NAME));
final JXList list = new JXList(new DefaultListModel());
list.setCellRenderer(new DefaultListRenderer(StringValues.FILE_NAME));
list.setVisibleRowCount(20);
JXFrame frame = wrapWithScrollingInFrame(tree, "search files");
frame.add(new JScrollPane(list), BorderLayout.SOUTH);
Action traverse = new AbstractAction("worker") {
@Override
public void actionPerformed(ActionEvent e) {
setEnabled(false);
Enumeration fileEnum = new PreorderModelEnumeration(files);
SwingWorker worker = new SearchWorker(fileEnum, list, tree);
PropertyChangeListener l = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
//T.imeOut("search end ");
setEnabled(true);
((SwingWorker) evt.getSource()).removePropertyChangeListener(this);
}
}
};
worker.addPropertyChangeListener(l);
// T.imeOn("starting search ... ");
worker.execute();
}
};
addAction(frame, traverse);
show(frame)
}
仅供参考:交叉发布到OTN's Swing forum和SwingLabs forum - 会尝试在最后发布所有输入的摘要(如果有的话: - )
附录
在一天结束时,我发现我问了错误的问题(或在错误的背景下正确的问题;-):“问题”是由假设的解决方案引起的,真实的要解决的任务是支持分层搜索算法(现在,AbstractSearchable严重偏离线性搜索)。
一旦问题解决了,下一个问题可能是框架可以做多少来支持具体的分层搜索。鉴于TreeModel的各种自定义实现,这最有可能只适用于最简单的。
在这里和其他论坛的讨论中提出了一些想法。在具体的上下文中,如果遍历很慢,首先度量:大多数内存模型都可以快速遍历,除了使用基本支持外,不需要做任何事情。
只有当遍历是瓶颈时(如SwingX的FileSystemModel实现中的f.i.),还需要做额外的工作:
无论慢速搜索的技术选项是什么,都需要解决相同的可用性问题:如何向最终用户提供延迟?这是一个完全不同的故事,可能更依赖于上下文/需求: - )
答案 0 :(得分:3)
SwingWorker
和TreeModel
都应该同步对公共基础DataModel
的访问权限。使数据的共享量(有效)不可变可以最小化开销。由于这是高度依赖于应用程序的,我不确定该视图可以为搜索不可见节点提供多少支持。