如何使用JTree侦听器动态更改带有CardLayout的JPanel?

时间:2021-02-08 12:36:48

I am trying to change the Panel with a CardLayout using the contents of a JTree. It is only working on the last selection. What listeners or changes should I do with my code?

我正在尝试使用JTree的内容使用CardLayout更改Panel。它只适用于最后的选择。我应该对我的代码做什么样的听众或更改?

I am also writing the text in the console and it seems to be getting the correct value. That is why it is frustrating me.

我也在控制台中写文本,似乎得到了正确的值。这就是为什么它令我感到沮丧。

My code should display 1st level when 1st level nodes are clicked and 2nd level when 2nd level nodes are clicked. I used

单击第一级节点时,我的代码应显示第一级,单击第二级节点时,我的代码应显示第二级。我用了

DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
                                .getLastSelectedPathComponent();

and it is only affecting the last components. How do I fix this? Thanks!

它只影响最后的组件。我该如何解决?谢谢!

Source code:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

public class ProblemTree2 extends JFrame {

    private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
    private DefaultTreeModel model = new DefaultTreeModel(root);
    private JTree tree = new JTree(model);
    private JPanel card;

    public ProblemTree2() {

        card = new JPanel(new CardLayout());
        card.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        JLabel label1 = new JLabel("1st level");
        JLabel label2 = new JLabel("2nd level");

        DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(
                "1st level: Child 1");
        n1.add(new DefaultMutableTreeNode("2nd level: Child l"));
        DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(
                "1st level: Child 2");
        n2.add(new DefaultMutableTreeNode("2nd level: Child 2"));
        DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(
                "1st level: Child 3");
        n3.add(new DefaultMutableTreeNode("2nd level: Child 3"));


        card.add(label1,"1st level: Child 1");
        card.add(label1,"1st level: Child 2");
        card.add(label1,"1st level: Child 3");

        card.add(label2,"2nd level: Child l");
        card.add(label2,"2nd level: Child 2");
        card.add(label2,"2nd level: Child 3");

        root.add(n1);
        root.add(n2);
        root.add(n3);

        tree.setEditable(true);
        tree.setSelectionRow(0);
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);


        tree.getSelectionModel().addTreeSelectionListener(
                new TreeSelectionListener() {
                    @Override
                    public void valueChanged(TreeSelectionEvent e) {

                        final CardLayout cards = (CardLayout) card
                                .getLayout();
                        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
                                .getLastSelectedPathComponent();
                        System.out.println(selectedNode.toString());
                        cards.show(card,selectedNode.toString());
                    }
                });


        JScrollPane scrollPane = new JScrollPane(tree);
        scrollPane.setPreferredSize(new Dimension(500,500));
        getContentPane().add(scrollPane, BorderLayout.WEST);
        getContentPane().add(card, BorderLayout.CENTER);

        setSize(1000, 600);
        setVisible(true);
    }

    public static void main(String[] arg) {
        ProblemTree2 pt = new ProblemTree2();
    }
}

1 个解决方案

#1


This...

card.add(label1, "1st level: Child 1");
card.add(label1, "1st level: Child 2");
card.add(label1, "1st level: Child 3");

card.add(label2, "2nd level: Child l");
card.add(label2, "2nd level: Child 2");
card.add(label2, "2nd level: Child 3");

is causing your problems, you can't assign the same instance of a component multiple keys.

导致您的问题,您不能分配多个组件的相同实例。

When you try and add the component a second time, it is first removed from it's parent container, which is causing the CardLayout to remove the "name" as well, meaning only the lines...

当您尝试第二次添加组件时,它首先从它的父容器中删除,这导致CardLayout也删除“名称”,这意味着只有行...

card.add(label1, "1st level: Child 3");
// and...
card.add(label2, "2nd level: Child 3");

are actually working (been added to the UI/CardLayout)

实际上正在工作(已添加到UI / CardLayout)

You will have to provide a new instance of the component for each name.

您必须为每个名称提供组件的新实例。

Alternatively, you could provide more details to your TreeNode that would allow you to ascertain which level it is and show the correct component for that level, meaning you would only have two components in your CardLayout, one for each level.

或者,您可以向TreeNode提供更多详细信息,以便确定它是哪个级别并显示该级别的正确组件,这意味着您的CardLayout中只有两个组件,每个级别一个。

The DefaultMutableTreeNode allows you to supply a "user" Object to it. By default, it uses the toString method of this object for the text for the node, but you can use a TreeCellRenderer to customise this or supply a value for the toString method of your "custom level" object

DefaultMutableTreeNode允许您向其提供“用户”对象。默认情况下,它使用此对象的toString方法作为节点的文本,但您可以使用TreeCellRenderer对其进行自定义或为“自定义级别”对象的toString方法提供值

#1


This...

card.add(label1, "1st level: Child 1");
card.add(label1, "1st level: Child 2");
card.add(label1, "1st level: Child 3");

card.add(label2, "2nd level: Child l");
card.add(label2, "2nd level: Child 2");
card.add(label2, "2nd level: Child 3");

is causing your problems, you can't assign the same instance of a component multiple keys.

导致您的问题,您不能分配多个组件的相同实例。

When you try and add the component a second time, it is first removed from it's parent container, which is causing the CardLayout to remove the "name" as well, meaning only the lines...

当您尝试第二次添加组件时,它首先从它的父容器中删除,这导致CardLayout也删除“名称”,这意味着只有行...

card.add(label1, "1st level: Child 3");
// and...
card.add(label2, "2nd level: Child 3");

are actually working (been added to the UI/CardLayout)

实际上正在工作(已添加到UI / CardLayout)

You will have to provide a new instance of the component for each name.

您必须为每个名称提供组件的新实例。

Alternatively, you could provide more details to your TreeNode that would allow you to ascertain which level it is and show the correct component for that level, meaning you would only have two components in your CardLayout, one for each level.

或者,您可以向TreeNode提供更多详细信息,以便确定它是哪个级别并显示该级别的正确组件,这意味着您的CardLayout中只有两个组件,每个级别一个。

The DefaultMutableTreeNode allows you to supply a "user" Object to it. By default, it uses the toString method of this object for the text for the node, but you can use a TreeCellRenderer to customise this or supply a value for the toString method of your "custom level" object

DefaultMutableTreeNode允许您向其提供“用户”对象。默认情况下,它使用此对象的toString方法作为节点的文本,但您可以使用TreeCellRenderer对其进行自定义或为“自定义级别”对象的toString方法提供值