• title: JTreeのノード追加、削除 tags: [JTree, JPopupMenu, TreeNode, TreeModel] author: aterai pubdate: 2011-05-02T16:45:24+09:00 description: JTreeのノードを選択してJPopupMenuを開き、そのノードの削除や名前変更、子ノードの追加を行います。

概要

JTreeのノードを選択してJPopupMenuを開き、そのノードの削除や名前変更、子ノードの追加を行います。

サンプルコード

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();
        DefaultMutableTreeNode parent =
          (DefaultMutableTreeNode) path.getLastPathComponent();
        DefaultMutableTreeNode child  = new DefaultMutableTreeNode("New");
        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();
        DefaultMutableTreeNode node =
          (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;
    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);
      }
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JPopupMenuを使って、選択したノードに子ノードの追加、削除、名前変更ができます。

  • 追加
    • DefaultTreeModel#insertNodeInto(...)メソッドを使用して、ノードを追加
  • 追加とリロード
    • DefaultMutableTreeNode#add(DefaultMutableTreeNode)メソッドを使ってノードを追加し、DefaultTreeModel#reload(...)、またはDefaultTreeModel#nodeStructureChanged(DefaultMutableTreeNode)で更新を通知
      • 兄弟ノードの展開状態などがリセットされてしまう
  • 削除
    • ルートノードでない場合(DefaultMutableTreeNode#isRoot()false)、DefaultTreeModel#removeNodeFromParent(DefaultMutableTreeNode)で削除
  • 名前変更
model.valueForPathChanged(path, str);
//もしくは、
//leaf.setUserObject(str);
//model.nodeChanged(leaf);

参考リンク

コメント