• category: swing folder: StartEditingPopupMenu title: JTreeのノード編集をPopupからのみに制限する tags: [JTree, JPopupMenu, TreeCellEditor, JOptionPane] author: aterai pubdate: 2010-04-19T13:46:44+09:00 description: JTreeのノード編集をマウスクリックではなくPopupからのみに制限します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTTy9Cda5I/AAAAAAAAAlA/6uCGiCD2iGY/s800/StartEditingPopupMenu.png hreflang:
       href: https://java-swing-tips.blogspot.com/2013/03/jtree-node-edit-only-from-jpopupmenu.html
       lang: en

概要

JTreeのノード編集をマウスクリックではなくPopupからのみに制限します。

サンプルコード

tree.setCellEditor(new DefaultTreeCellEditor(
    tree, (DefaultTreeCellRenderer) tree.getCellRenderer()) {
  @Override public boolean isCellEditable(EventObject e) {
    return !(e instanceof MouseEvent) && super.isCellEditable(e);
  }

  // @Override protected boolean canEditImmediately(EventObject e) {
  //   // ((MouseEvent) e).getClickCount() > 2
  //   return (e instanceof MouseEvent) ? false : super.canEditImmediately(e);
  // }
});
tree.setEditable(true);
tree.setComponentPopupMenu(new TreePopupMenu());
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、DefaultTreeCellEditor#isCellEditableメソッドをオーバーライドしたCellEditorを設定することでノードをマウスでクリックしても編集開始できないように制限しています。


  • JTree#startEditingAtPathメソッドを使用してTreeCellEditorで編集する方法と、JOptionPaneを開いて編集する方法の二種類をメニューに追加
    • 入力された文字列をDefaultTreeModel#valueForPathChangedメソッドでJTreeに反映
      public TreePopupMenu() {
        super();
        add(new JMenuItem(new AbstractAction("Edit") {
          @Override public void actionPerformed(ActionEvent e) {
            JTree tree = (JTree) getInvoker();
            if (path != null) {
              tree.startEditingAtPath(path);
            }
          }
        }));
        add(new JMenuItem(new AbstractAction("Edit Dialog") {
          @Override public void actionPerformed(ActionEvent e) {
            JTree tree = (JTree) getInvoker();
            if (path == null) {
              return;
            }
            Object node = path.getLastPathComponent();
            if (node instanceof DefaultMutableTreeNode) {
              DefaultMutableTreeNode leaf = (DefaultMutableTreeNode) node;
              textField.setText(leaf.getUserObject().toString());
              int result = JOptionPane.showConfirmDialog(
                  tree, textField, "Rename",
                  JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
              if (result == JOptionPane.OK_OPTION) {
                String str = textField.getText();
                if (!str.trim().isEmpty()) {
                  ((DefaultTreeModel) tree.getModel()).valueForPathChanged(path, str);
                }
              }
            }
          }
        }));
        // ...
      

参考リンク

コメント