当前位置: 首页 > 面试题库 >

从CellEditorListener获取编辑的TreeNode

李招
2023-03-14
问题内容

之前我问过如何在重命名TreeNode时触发事件(此处)。我的问题已经回答,但是我遇到了另一个问题。我需要访问在CellEditorListener的editingStopped事件中正在编辑的TreeNode。这是我要做的代码:

package com.gamecreator;

import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultTreeCellEditor;

public class CustomCellEditorListener implements CellEditorListener {
    public CustomCellEditorListener() {

    }

    public void editingCanceled(ChangeEvent e) {

    }

    public void editingStopped(ChangeEvent e) {
        DefaultTreeCellEditor editor = (DefaultTreeCellEditor) e.getSource(); //This gives me the error.
        CustomTreeNode node = //What do I put here???;
        node.getResource().setName((String) node.getUserObject());

        //For debugging
        System.out.println(node.getResource().getName());
    }
}

我收到此错误:

线程“ AWT-EventQueue-0”中的异常java.lang.ClassCastException:javax.swing.tree.DefaultTreeCellEditor $ 1无法转换为javax.swing.tree.DefaultTreeCellEditor

编辑:在另一种尝试,我在CustomCellEditorListener中使用此代码

public void editingStopped(ChangeEvent e) {
    TreePath path = ((CustomTreeCellEditor) e.getSource()).getLastPath();  //This gives me the error.
    CustomTreeNode node = (CustomTreeNode) path.getLastPathComponent();
    node.getResource().setName((String) node.getUserObject());

    //For debugging
    System.out.println(node.getResource().getName());
}

和这段代码在CustomTreeCellEditor中

public TreePath getLastPath() {
    return lastPath;
}

我遇到了同样的错误(我希望会)。我应该做的工作是,所以唯一剩下的真正的问题是:“我为什么会收到错误以及如何解决该错误?”,但是,如果有人有更好的方法可以做到这一点,我愿意听。

编辑2:我已经做了什么,我试图完成,可以发现一个小例子在这里(这是一个Eclipse存档)


问题答案:

看来,要编辑的名字ResourceDefaultMutableTreeNode。正如您看到的,的源ChangeEvent发送到editingStopped()在没有一个DefaultTreeCellEditor; 它是编辑器的(匿名)UI委托。

而是getCellEditorValue()在您的中进行覆盖DefaultTreeCellEditor,如下所示。在DefaultTreeCellRenderer简单地调用toString(),通过convertValueToText(),它访问的用户对象DefaultMutableTreeNode。

附录:请注意,isCellEditable()确保只能编辑叶节点。

正如@kleopatra在注释中指出的那样,先前的TreeCellEditor实现无效,因为它修改了正在编辑的节点。下面的修订版本创建了一个具有更新名称的新节点;一个拷贝构造函数是在这方面非常有用。好处是userObject遗迹仍然是Resource。另请参见此替代方法。

/**
 * @see https://stackoverflow.com/a/12651990/230513
 * @see https://stackoverflow.com/a/11639595/230513
 * @see https://stackoverflow.com/a/11113648/230513
 */
public class TreeEditDemo extends JPanel {

    private JTree tree;
    private DefaultMutableTreeNode root;
    private DefaultTreeCellEditor editor;
    private JLabel label = new JLabel(" ", JLabel.CENTER);

    public TreeEditDemo() {
        super(new BorderLayout());
        root = new DefaultMutableTreeNode("Nodes");
        root.add(new DefaultMutableTreeNode(new Resource("one")));
        root.add(new DefaultMutableTreeNode(new Resource("two")));
        root.add(new DefaultMutableTreeNode(new Resource("three")));
        final DefaultTreeModel treeModel = new DefaultTreeModel(root);
        tree = new JTree(treeModel);
        tree.setEditable(true);
        editor = new MyTreeCellEditor(tree,
            (DefaultTreeCellRenderer) tree.getCellRenderer());
        tree.setCellEditor(editor);
        tree.getInputMap().put(
            KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "startEditing");
        this.add(new JScrollPane(tree));
        this.add(label, BorderLayout.SOUTH);
        tree.addTreeSelectionListener(new TreeSelectionListener() {

            @Override
            public void valueChanged(TreeSelectionEvent e) {
                TreePath path = e.getNewLeadSelectionPath();
                if (path != null) {
                    DefaultMutableTreeNode node =
                        (DefaultMutableTreeNode) path.getLastPathComponent();
                    if (node.isLeaf()) {
                        Resource user = (Resource) node.getUserObject();
                        label.setText(user.toString());
                    } else {
                        label.setText(" ");
                    }
                }
            }
        });
        editor.addCellEditorListener(new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {
                label.setText(editor.getCellEditorValue().toString());
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
            }
        });
    }

    private static class MyTreeCellEditor extends DefaultTreeCellEditor {

        public MyTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
            super(tree, renderer);
        }

        @Override
        public Object getCellEditorValue() {
            String value = (String) super.getCellEditorValue();
            return new Resource(value);
        }

        @Override
        public boolean isCellEditable(EventObject e) {
            return super.isCellEditable(e)
                && ((TreeNode) lastPath.getLastPathComponent()).isLeaf();
        }
    }

    private static class Resource {

        String name;

        public Resource(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return getName();
        }
    }

    private void display() {
        JFrame f = new JFrame("TreeEditorDemo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TreeEditDemo().display();
            }
        });
    }
}


 类似资料:
  • 我想在用户在EditText中键入文本时将文本放入我的应用程序中的某个字符串中,并使用它来生动地在活动上显示它(在不同的视图中...) - 就像谷歌的实时/即时搜索工作一样...

  • 本文向大家介绍easy ui datagrid 从编辑框中获取值的方法,包括了easy ui datagrid 从编辑框中获取值的方法的使用技巧和注意事项,需要的朋友参考一下 如下所示: 以上这篇easy ui datagrid 从编辑框中获取值的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 简短版本: 如何从Physics Body编辑器中获取基本的< code > com . badlogic . math . gdx . polygon ? 长版本: 我已经为LibGDX实现了加载器,但是加载器通过它的内部 类使用它自己的内部类。但这似乎并不是很“微不足道”。我想到的东西看起来像这样: 这是相当麻烦的,我有这个完整的加载器,只是为了剥离它构建的所有内容,直到索引,并从中构建我自己

  • 我有一个可编辑的div内容,我保存了一些html文本。我添加了属性< code>runat="server",并希望用c#获得html文本内容。有人能帮我吗?这是我的< code>div PS:不起作用!! PS2:我的目的通常就像这里一样。我想从允许的div中获取数据并将其用作HTML字符串 已解决:

  • 问题内容: 我正在使用Eclipse IDE。首先,我想开发一个插件,这个插件使我可以将整个源代码作为一个简单的字符串来获取。 我使用模板“ hello world命令”制作了一个简单的“ hello the world”插件。现在,我正在寻找从Eclipse编辑器中获取源代码,并使用System.out.println()进行显示;而不是显示HELLO THE WORLD。 我试过了,但是它只显

  • 我有一个数据库里的罐头电子邮件列表。“感谢您成为会员”,“感谢您在途中购买”—诸如此类的话。我正在使用引导模式来编辑这些电子邮件。当我单击编辑按钮时,模式会下拉,并用数据库中的数据填充:电子邮件名称、主题、正文。我正在使用将数据传递给引导模式来实现这一点。效果很好。现在我使用summernote作为我的富文本编辑器。 以下是我的文本区域,显示未编辑的数据: summernote类是如何将数据定向到