JTreeのノードを名前で検索して表示のフィルタリングを行う
Total: 4126, Today: 1, Yesterday: 1
Posted by aterai at
Last-modified:
Summary
JTreeのノードを検索し、そのTreePathが条件に一致しないノードを非表示にするフィルタリングを行います。
Screenshot

Advertisement
Source Code Examples
tree.setCellRenderer(new DefaultTreeCellRenderer() {
private final JLabel emptyLabel = new JLabel();
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf,
int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
FilterableNode uo = (FilterableNode) node.getUserObject();
return uo.status ? c : emptyLabel;
}
});
fireDocumentChangeEvent();
// ...
private void fireDocumentChangeEvent() {
String q = field.getText();
TreePath rtp = tree.getPathForRow(0);
if (q.isEmpty()) {
resetAll(tree, rtp, true);
((DefaultTreeModel) tree.getModel()).reload();
// visitAll(tree, rtp, true);
} else {
visitAll(tree, rtp, false);
searchTree(tree, rtp, q);
}
}
View in GitHub: Java, KotlinDescription
上記のサンプルでは、指定された条件に一致しないノードを高さ0のTreeCellRendererで描画することで、ノードのフィルタリングを行っています。
TreePathに指定された接頭辞で始まるTreeNodeが含まれている場合、そのノードのUserObjectに表示フラグを立てる- 例:
fooで検索した場合foodノード以下の子ノードも表示される
- 例:
TreeCellRenderer内でUserObjectを取得し、非表示の場合は高さ0のJLabelをレンダラーとして返すtree.setRowHeight(-1);と設定しているので各ノードの描画を行うレンダラーの推奨サイズが行の高さとして使用される
- 高さ
0のノードに対しても関連ノード間を繋ぐ点線が引かれる場合がある(LookAndFeelに依存)のでこれを非表示にする場合は、UIManager.put("Tree.paintLines", Boolean.FALSE);、またはtree.putClientProperty("JTree.lineStyle", "None");などを使用する
Reference
- java - Filter jtree - keeping all nodes and children of nodes that match criteria - Stack Overflow
- JTree#setRowHeight(int) (Java Platform SE 8)