JTreeのノードを名前で検索して表示のフィルタリングを行う
Total: 3749
, Today: 1
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JTree
のノードを検索し、そのTreePath
が条件に一致しないノードを非表示にするフィルタリングを行います。
Screenshot
Advertisement
サンプルコード
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, Kotlin解説
上記のサンプルでは、指定された条件に一致しないノードを高さ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");
などを使用する
参考リンク
- java - Filter jtree - keeping all nodes and children of nodes that match criteria - Stack Overflow
- JTree#setRowHeight(int) (Java Platform SE 8)