当前位置: 首页 > 知识库问答 >
问题:

动态添加节点到非叶节点不工作|JTree

洪通
2023-03-14

我试图在弹出组件和JMenuItem组件的click action事件中向JTree动态添加节点。我右键单击节点组件并添加另一个节点。添加节点适用于叶节点,但不适用于非叶节点。我不知道代码有什么问题。似乎添加了节点,但Gui没有更新。

平台:Windows 7

Java Java版本“1.7.0\u 17”Java(TM)SE运行时环境(build 1.7.0\u 17-b02)Java HotSpot(TM)64位服务器VM(build 23.7-b01,混合模式)

package test;

/**
 *
 * @author Rajan
 */

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 *
 * @author Rajan Prasad Upadhyay
 */
public class TreeTest {

    String name = "name";

    public static void main(String[] args) {
        javax.swing.JFrame topFrame = new JFrame();
        javax.swing.JPanel topPanel = new JPanel();
        javax.swing.JScrollPane leftScrollPane = new JScrollPane();
        javax.swing.JTree leftTree = new JTree();

        topFrame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        //layouts
        topFrame.setLayout(new BorderLayout());
        topPanel.setLayout(new BorderLayout());

        // addition of components
//        topPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE));
        topPanel.add(leftScrollPane);

        leftScrollPane.getViewport().add(leftTree);

        addExperimentEvents(leftTree);

        topFrame.setSize(600, 500);
        topFrame.setContentPane(topPanel);
        topFrame.setVisible(true);
    }

    public static void addExperimentEvents(JTree tree) {
        MouseAdapter ma = new MouseAdapter() {
            private void myPopupEvent(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                final JTree tree = (JTree) e.getSource();
                TreePath path = tree.getPathForLocation(x, y);
                if (path == null) {
                    return;
                }

                tree.setSelectionPath(path);

                Object obj = (Object) path.getLastPathComponent();

                String label = "Add:";// + obj.toString();
                JPopupMenu popup = new JPopupMenu("Menu");

                JMenu sectionsMenu = new JMenu("Sections");
                JMenuItem menuItem1 = new JMenuItem("Item1");
                sectionsMenu.add(menuItem1);
                JMenuItem menuItem2 = new JMenuItem("Item2");
                sectionsMenu.add(menuItem2);

                JMenuItem item = new JMenuItem(label);
                item.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent ae) {
                        System.out.println("Editing the tree");
                        DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
                                .getLastSelectedPathComponent();
                        TreeNode root = (TreeNode) tree.getModel().getRoot();
                        DefaultTreeModel model = new DefaultTreeModel(root);

                        if (selNode != null) {
                            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node" + (selNode.getChildCount() + 1));
                            model.insertNodeInto(newNode, selNode, selNode.getChildCount());//
                            //model.insertNodeInto(newNode, (MutableTreeNode) root, root.getChildCount());
                            tree.expandPath(new TreePath(model.getPathToRoot(newNode.getParent())));

                            TreeNode[] nodes = model.getPathToRoot(newNode);
                            TreePath path = new TreePath(nodes);

                            System.out.println(selNode.getChildCount() + ", " + path);
                            tree.scrollPathToVisible(path);
                            tree.setSelectionPath(path);
                            tree.startEditingAtPath(path);
                            model.reload((TreeNode) model.getRoot());
                        }else{
                            System.out.println("selNode is null");
                        }
                    }
                });
                //addHoverAction(item);//
                //item.add(new JMenuItem("page"));

                popup.add(item);
                popup.add(new JMenuItem("Move: "));
                popup.add(sectionsMenu);
                popup.show(tree, x, y);
            }

            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    myPopupEvent(e);
                }
            }

            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    myPopupEvent(e);
                }
            }
        };
        tree.addMouseListener(ma);
    }

    public static void addHoverAction(final JComponent com) {

        MouseAdapter adapter = new MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                System.out.println("mouse Entered: ");
                if (true) {
                    JPopupMenu pop = new JPopupMenu();
                    pop.add(new JMenuItem("Node"));

                    pop.show(com.getParent(), com.getWidth(), com.getHeight());
                }
            }
        };
        com.addMouseListener(adapter);
    }
}

感谢您在advanced中提供问题的解决方案和描述。

共有2个答案

杜阳炎
2023-03-14

有一个Swing教程就是这样做的。您可以看到他们动态添加、删除和编辑树的完整代码。他们的代码很短。

凌波峻
2023-03-14

使用下线

DefaultTreeModel model = (DefaultTreeModel) tree.getModel();

而不是

DefaultTreeModel model = new DefaultTreeModel(root);

最后展开所需的节点。

下面是关于如何展开或折叠所有JTree节点的示例代码?

 类似资料:
  • 我正在尝试构建一个在JavaFX中实现群聊的聊天应用程序。我想在边框窗格内创建一个滚动窗格,该窗格将包含用户所属的所有组。当用户加入时,需要将组图标(ImageViews)动态添加(在场景生成器中无法完成)到滚动窗格(在HBox内)。 目前,我正在使用一个SceneController类,该类负责所有阶段和场景更改。 我已经创建了一个FXML文件(使用场景生成器),其中包含一个边框窗格和一个滚动窗

  • 问题内容: 有人有使用过保险丝图形工具包的经验吗?是否可以更改已经显示的图形,即。添加/删除节点和/或边缘,并正确调整显示? 例如,prefuse附带一个示例,该示例形象化了一个朋友网络: http://prefuse.org/doc/manual/introduction/example/Example.java 我想做的事情与此类似: 但这似乎不起作用。有什么提示吗? 问题答案: 正如我在另一

  • 有什么工作可以做吗?可能是一种远程通知每个节点将新节点添加到集群的方法吗?

  • 问题内容: 我在地图操作中使用a 作为共享计数器。但是似乎我没有正确使用它,因为工作节点上计数器的状态没有更新。这是我的柜台类的样子: 据我了解的文档,当应用程序在多个工作程序节点中运行时,这应该可以正常工作: 累加器是仅通过关联和交换操作“累加”的变量,因此可以有效地并行支持。它们可用于实现计数器(如在MapReduce中)或总和。Spark本身支持数字类型的累加器,程序员可以添加对新类型的支持

  • 我有一棵看起来像上面的树,由一个链接结构表示: 我的目标是找到从根节点到叶节点的所有路径。 我的树遍历算法如下所示: 当我运行它时,我确信树正在按图所示构建。我已经测试过了。然而,我无法找出我的树遍历分割错误的原因。 我得到的输出是: 我已经在高度较小的树上测试了它,它是有效的。但是出于某种原因,它不适用于高度大于2的树。我认为这是树出了问题,我检查并打印了每个父级、左子级和右子级,它们打印出来如

  • 我正在玩一个链接列表类项目的指针,我不知道如何创建到新节点的链接。我有一个类,它包含像这样的方法来操作数据结构。我希望这些节点是从csv文件中读取的出价。 当我从CSV加载所有数据时,我想 创建一个新的出价 将新的出价传递给函数 设置Bid对象的nextBid指针,并更新链接列表的尾部 我将不胜感激为每个出价对象创建新地址的任何指针,因为现在尾节点只'记得'第一个出价的地址。 我复制了下面的代码,