• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTreeのノード追加、削除
#navi(../)
#tags(JTree, JPopupMenu, TreeNode, TreeModel)
RIGHT:Posted by &author(aterai); at 2011-05-02
* JTreeのノード追加、削除 [#y57e98ab]
`JTree`にノードを追加、削除します。
---
category: swing
folder: AddNode
title: JTreeのノード追加、削除
tags: [JTree, JPopupMenu, TreeNode, TreeModel]
author: aterai
pubdate: 2011-05-02T16:45:24+09:00
description: JTreeのノードを選択してJPopupMenuを開き、そのノードの削除や名前変更、子ノードの追加を行います。
image: https://lh6.googleusercontent.com/_9Z4BYR88imo/Tb5bkDzXJHI/AAAAAAAAA6c/qxz0Vzwy4Ts/s800/AddNode.png
---
* 概要 [#summary]
`JTree`のノードを選択して`JPopupMenu`を開き、そのノードの削除や名前変更、子ノードの追加を行います。

#download
#ref(https://lh6.googleusercontent.com/_9Z4BYR88imo/Tb5bkDzXJHI/AAAAAAAAA6c/qxz0Vzwy4Ts/s800/AddNode.png)
#download(https://lh6.googleusercontent.com/_9Z4BYR88imo/Tb5bkDzXJHI/AAAAAAAAA6c/qxz0Vzwy4Ts/s800/AddNode.png)

** サンプルコード [#l888db92]
* サンプルコード [#sourcecode]
#code(link){{
class TreePopupMenu extends JPopupMenu {
  private TreePath path;
  public TreePopupMenu() {
    super();
    add(new AbstractAction("add") {
      @Override public void actionPerformed(ActionEvent e) {
        JTree tree = (JTree)getInvoker();
        DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
        JTree tree = (JTree) getInvoker();
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        DefaultMutableTreeNode parent =
          (DefaultMutableTreeNode)path.getLastPathComponent();
          (DefaultMutableTreeNode) path.getLastPathComponent();
        DefaultMutableTreeNode child  = new DefaultMutableTreeNode("New");
        //model.insertNodeInto(child, parent, 0);
        parent.add(child);
        model.nodeStructureChanged(parent);
        model.insertNodeInto(child, parent, parent.getChildCount());
        // parent.add(child);
        // model.reload(); // = model.nodeStructureChanged(parent);
        tree.expandPath(path);
      }
    });
    add(new AbstractAction("remove") {
      @Override public void actionPerformed(ActionEvent e) {
        JTree tree = (JTree)getInvoker();
        DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
        JTree tree = (JTree) getInvoker();
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        DefaultMutableTreeNode node =
          (DefaultMutableTreeNode)path.getLastPathComponent();
        //if(path.getParentPath()!=null) {
        if(!node.isRoot()) {
          (DefaultMutableTreeNode) path.getLastPathComponent();
        // if (path.getParentPath() != null) {
        if (!node.isRoot()) {
          model.removeNodeFromParent(node);
        }
      }
    });
  }

  @Override public void show(Component c, int x, int y) {
    JTree tree = (JTree)c;
    JTree tree = (JTree) c;
    TreePath[] tsp = tree.getSelectionPaths();
    if(tsp!=null) {
      path = tree.getPathForLocation(x, y);
      if(path!=null && Arrays.asList(tsp).contains(path)) {
        super.show(c, x, y);
      }
    path = tree.getPathForLocation(x, y);
    if (path != null && Arrays.asList(tsp).contains(path)) {
      super.show(c, x, y);
    }
  }
}
}}

** 解説 [#f470d783]
上記のサンプルでは、`JPopupMenu`を使って、選択したノードに子ノードの追加、削除、名前変更ができます。
* 解説 [#explanation]
上記のサンプルでは、`JPopupMenu`を使用して選択したノードに対して子ノードの追加、削除、名前変更ができます。

- 追加
-- `DefaultMutableTreeNode#add(DefaultMutableTreeNode)`メソッドを使ってノードを追加し、`DefaultTreeModel#nodeStructureChanged(DefaultMutableTreeNode)`で更新を通知
-- `DefaultTreeModel#insertNodeInto(...)`メソッドを使用する方法もある
-- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeModel.html#insertNodeInto-javax.swing.tree.MutableTreeNode-javax.swing.tree.MutableTreeNode-int- DefaultTreeModel#insertNodeInto(...)]メソッドを使用して、ノードを追加
- 追加とリロード
-- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultMutableTreeNode.html#add-javax.swing.tree.MutableTreeNode- DefaultMutableTreeNode#add(MutableTreeNode)]メソッドを使ってノードを追加し、[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeModel.html#reload-javax.swing.tree.TreeNode- DefaultTreeModel#reload(...)]、または[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeModel.html#nodeStructureChanged-javax.swing.tree.TreeNode- DefaultTreeModel#nodeStructureChanged(TreeNode)]メソッドで更新を通知
--- 兄弟ノードの展開状態などがリセットされてしまう
- 削除
-- ルートノードでない場合(`DefaultMutableTreeNode#isRoot()`が偽)、`DefaultTreeModel#removeNodeFromParent(DefaultMutableTreeNode)`で削除
-- ルートノード以外の場合(`DefaultMutableTreeNode#isRoot()`が`false`)[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeModel.html#removeNodeFromParent-javax.swing.tree.MutableTreeNode- DefaultTreeModel#removeNodeFromParent(MutableTreeNode)]メソッドで削除
- 名前変更
-- [[JTreeのノード編集をPopupからのみに制限する>Swing/StartEditingPopupMenu]]と同じ

-- [[JTreeのノード編集をJPopupMenuからのみに制限する>Swing/StartEditingPopupMenu]]と同じ
#code{{
model.valueForPathChanged(path, str);
//もしくは、
//leaf.setUserObject(str);
//model.nodeChanged(leaf);
// もしくは、
// leaf.setUserObject(str);
// model.nodeChanged(leaf);
}}

** 参考リンク [#gb30e7d7]
* 参考リンク [#reference]
- [[JTreeのノード上でJPopupMenuを表示 >Swing/TreeNodePopupMenu]]
- [[JTreeのノード編集をPopupからのみに制限する>Swing/StartEditingPopupMenu]]
- [[JTreeのノード編集をJPopupMenuからのみに制限する>Swing/StartEditingPopupMenu]]
- [[JTreeの選択されたノードの前後に新規ノードを挿入する>Swing/InsertSiblingNode]]

** コメント [#ad4d46ba]
- ソースなどのリンク切れを修正。 -- [[aterai]] &new{2011-05-06 (金) 18:46:23};
* コメント [#comment]
#comment
- ソースなどのリンク切れを修正。 -- &user(aterai); &new{2011-05-06 (金) 18:46:23};

#comment