• 追加された行はこの色です。
  • 削除された行はこの色です。
---
category: swing
folder: SearchBox
title: JTreeのノードを検索する
tags: [JTree, TreeModel, TreePath, TreeNode]
author: aterai
pubdate: 2009-01-12T18:57:42+09:00
description: JTreeを検索して、一致するアイテムを選択します。
image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSs3gdysI/AAAAAAAAAjM/r_j-mrb83aU/s800/SearchBox.png
---
* 概要 [#summary]
`JTree`を検索して、一致するアイテムを選択します。

#download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSs3gdysI/AAAAAAAAAjM/r_j-mrb83aU/s800/SearchBox.png)

* サンプルコード [#sourcecode]
#code(link){{
protected static void searchTree(
    JTree tree, TreePath path, String q,
    List<TreePath> rollOverPathLists) {
  Object o = path.getLastPathComponent();
  if (o instanceof TreeNode) {
    TreeNode node = (TreeNode) o;
    if (node.toString().startsWith(q)) {
      rollOverPathLists.add(path);
      tree.expandPath(path.getParentPath());
    }
    if (!node.isLeaf()) {
      // Java 9: Enumeration<TreeNode> e = node.children();
      Enumeration<?> e = node.children();
      while (e.hasMoreElements()) {
        searchTree(tree, path.pathByAddingChild(e.nextElement()),
                   q, rollOverPathLists);
      }
    }
  }
}
}}

* 解説 [#explanation]
上記のサンプルでは、選択された`JTree`のノード以下に検索文字列と一致するノードがあれば、`JTree#addSelectionPath(TreePath)`メソッドで選択しています。
上記のサンプルでは、選択された`JTree`のノード以下に検索文字列と一致するノードを検索して`JTree#addSelectionPath(TreePath)`メソッドで選択しています。

----
- [https://community.oracle.com/thread/1357454 Swing - how to get everything in DefaultTreeNode]のAndre_Uhresさんの投稿のように`TreeModel`を使って検索する方法もある

#code{{
// <blockquote cite="https://community.oracle.com/thread/1357454">
public void traverse(JTree tree) {
  TreeModel model = tree.getModel();
  Object root;
  if (model != null) {
    root = model.getRoot();
    walk(model, root);
  } else {
    System.out.println("Tree is empty.");
  }
}

protected void walk(TreeModel model, Object o) {
  int cc = model.getChildCount(o);
  for (int i = 0; i < cc; i++) {
    DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(o, i);
    if (model.isLeaf(child)) {
      System.out.println(child);
    } else {
      System.out.println(child);
      walk(model, child);
    }
  }
}
// </blockquote>
}}

----
- 以下は`DefaultMutableTreeNode#depthFirstEnumeration()`を使用して`bananas`を検索
-- [[JTreeのノードを走査する>Swing/TraverseAllNodes]]

#code{{
TreeModel model = tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
Enumeration depth = root.depthFirstEnumeration();
while (depth.hasMoreElements()) {
  DefaultMutableTreeNode node = (DefaultMutableTreeNode) depth.nextElement();
  if (node != null && "bananas".equals(node.toString())) {
    TreePath path = new TreePath(node.getPath());
    tree.setSelectionPath(path);
    tree.scrollPathToVisible(path);
    return;
  }
}
}}

* 参考リンク [#reference]
- [[JTreeのノードを展開・折り畳み>Swing/ExpandAllNodes]]
- [https://community.oracle.com/thread/1357454 Swing - how to get everything in DefaultTreeNode]
- [[JTreeで条件に一致するノードを検索しハイライト>Swing/TreeNodeHighlightSearch]]
- [[JTreeのノードを走査する>Swing/TraverseAllNodes]]

* コメント [#comment]
#comment
- ソースを拝見させていただきましたが, 要素の挿入の箇所がさっぱりわかりません... -- &user(taji); &new{2010-01-20 (水) 00:38:18};
- 途中で切れてしまい失礼しました. できればどこで挿入しているのか教えていただけませんか? -- &user(taji); &new{2010-01-20 (水) 00:39:44};
-- `JTree`のデフォルトコンストラクタがサンプルモデルを持つ`JTree`を返しているので、`%JAVA_HOME%/src.zip`を展開して、`JTree()`を見るのがよいと思います。そこからたどって行けば`protected static TreeModel getDefaultTreeModel()`の中で、`TreeModel`を作って要素(ノード)を挿入している様子が分かります。 -- &user(aterai); &new{2010-01-20 (水) 11:15:33};

#code{{
/**
 * Creates and returns a sample <code>TreeModel</code>.
 * Used primarily for beanbuilders to show something interesting.
 *
 * @return the default <code>TreeModel</code>
 */
protected static TreeModel getDefaultTreeModel() {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
    DefaultMutableTreeNode parent;

    parent = new DefaultMutableTreeNode("colors");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("blue"));
    parent.add(new DefaultMutableTreeNode("violet"));
    parent.add(new DefaultMutableTreeNode("red"));
    parent.add(new DefaultMutableTreeNode("yellow"));

    parent = new DefaultMutableTreeNode("sports");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("basketball"));
    parent.add(new DefaultMutableTreeNode("soccer"));
    parent.add(new DefaultMutableTreeNode("football"));
    parent.add(new DefaultMutableTreeNode("hockey"));

    parent = new DefaultMutableTreeNode("food");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("hot dogs"));
    parent.add(new DefaultMutableTreeNode("pizza"));
    parent.add(new DefaultMutableTreeNode("ravioli"));
    parent.add(new DefaultMutableTreeNode("bananas"));
    return new DefaultTreeModel(root);
}
}}

- `JTree#getNextMatch(...)`は、展開されているノードのみ検索する? -- &user(aterai); &new{2010-11-18 (木) 01:40:07};
- 一致するノードが複数ある場合、ボタンクリックで選択状態がループするように変更。 -- &user(aterai); &new{2011-09-15 (木) 21:32:23};

#comment