简体   繁体   English

动态更改 JTree 的数据模型

[英]dynamically changing data model for JTree

I have a small GUI application, that processes mouse clicks, and stores them in a list:我有一个小的 GUI 应用程序,它处理鼠标点击,并将它们存储在一个列表中:

package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGUI extends JFrame {

    private final List<String> objects = new ArrayList<>();
    private TestTree testTree;

    final JPanel canvas = new JPanel() {
        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponent(g);
            g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
            g.setColor(Color.BLACK);
            for (final String object : objects) {
                final String[] parts = object.split("--");
                g.drawOval(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 5, 5);
            }
        }
    };

    public TestGUI() {
        final Container cp = getContentPane();
        cp.setLayout(new BorderLayout());
        cp.add(canvas, BorderLayout.CENTER);
        testTree = new TestTree(objects);
        cp.add(testTree, BorderLayout.EAST);
        setTitle("TestGUI");
        canvas.addMouseListener(new MouseListener() {
            @Override
            public void mouseReleased(MouseEvent me) {}
            @Override
            public void mousePressed(MouseEvent me) {}
            @Override
            public void mouseExited(MouseEvent me) {}
            @Override
            public void mouseEntered(MouseEvent me) {}
            @Override
            public void mouseClicked(MouseEvent me) {
                objects.add(me.getX() + "--" + me.getY());
                testTree.update();
                canvas.repaint();
            }
        });
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 500);
        setVisible(true);
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestGUI();
            }
        });
    }

}

I want to represent an overview of the list using a JTree at the side of the canvas.我想使用画布一侧的 JTree 来表示列表的概览。 The class responsible for the JTree is as follows:负责JTree的类如下:

package test;

import java.util.List;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class TestTree extends JPanel {

    final List<String> objects;

    private JTree tree;
    private final DefaultMutableTreeNode root;

    public TestTree(final List<String> theObjects) {
        objects = theObjects;

        root = new DefaultMutableTreeNode("root");
        tree = new JTree(root);

        add(new JScrollPane(tree));
    }

    private void updateTree(final List<String> objects) {
        root.removeAllChildren();
        final DefaultMutableTreeNode result = new DefaultMutableTreeNode(objects.size() + " objects");
        for (final String object : objects) {
            final DefaultMutableTreeNode objectNode = new DefaultMutableTreeNode(object);
            result.add(objectNode);
        }
        root.add(result);
        tree.updateUI();
    }

    public void update() {
        updateTree(objects);
        tree = new JTree(root);
        add(new JScrollPane(tree));
    }

}

So, which is the correct way of updating the JTree by submitting the list?那么,通过提交列表来更新 JTree 的正确方法是什么? Because after some clicks my application renders a seperate tree for each added element, instead of one tree that gets updated over time:因为单击几次后,我的应用程序为每个添加的元素呈现一个单独的树,而不是一个随时间更新的树: 截屏

Any suggestions would be appreciated.任何建议,将不胜感激。 Thank you very much!非常感谢!

Your problem is in method update() of class TestTree .您的问题出在TestTree类的update()方法中。 You keep adding another JScrollPane to the TestTree .您不断添加另一个JScrollPaneTestTree You only want one JScrollPane .您只需要一个JScrollPane

You correctly update the model of the JTree and that's all you need to do.您正确更新了JTree的模型,这就是您需要做的全部工作。 The JTree will automatically update itself whenever its model changes. JTree将在其模型更改时自动更新自身。

Also, don't set the size of the JFrame .另外,不要设置JFrame的大小。 Set the size of its components and call method pack() which will make the JFrame big enough to contain all its components.设置其组件的大小并调用pack()方法,这将使JFrame足够大以包含其所有组件。

In the below code I have commented out the lines you need to remove from your code.在下面的代码中,我注释掉了您需要从代码中删除的行。

Class TestTree类测试TestTree

package test;

import java.awt.Dimension;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class TestTree extends JPanel {
    final List<String> objects;

    private JTree tree;
    private final DefaultMutableTreeNode root;

    public TestTree(final List<String> theObjects) {
        objects = theObjects;
        root = new DefaultMutableTreeNode("root");
        tree = new JTree(root);
        JScrollPane scrollPane = new JScrollPane(tree);
        scrollPane.setPreferredSize(new Dimension(100, 490));
        add(scrollPane);
    }

    private void updateTree() {
        root.removeAllChildren();
        final DefaultMutableTreeNode result = new DefaultMutableTreeNode(objects.size() + " objects");
        for (String object : objects) {
            final DefaultMutableTreeNode objectNode = new DefaultMutableTreeNode(object);
            result.add(objectNode);
        }
        root.add(result);
        tree.updateUI();
    }

    public void update() {
        updateTree();
//        tree = new JTree(root);
//        add(new JScrollPane(tree));
    }
}

Class TestGUITestGUI

package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGUI extends JFrame {

    private final List<String> objects = new ArrayList<>();
    private TestTree testTree;

    final JPanel canvas = new JPanel() {
        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponent(g);
            g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
            g.setColor(Color.BLACK);
            for (final String object : objects) {
                final String[] parts = object.split("--");
                g.drawOval(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 5, 5);
            }
        }
    };

    public TestGUI() {
        final Container cp = getContentPane();
        cp.setLayout(new BorderLayout());
        cp.add(canvas, BorderLayout.CENTER);
        testTree = new TestTree(objects);
        cp.add(testTree, BorderLayout.EAST);
        setTitle("TestGUI");
        canvas.addMouseListener(new MouseListener() {
            @Override
            public void mouseReleased(MouseEvent me) {}
            @Override
            public void mousePressed(MouseEvent me) {}
            @Override
            public void mouseExited(MouseEvent me) {}
            @Override
            public void mouseEntered(MouseEvent me) {}
            @Override
            public void mouseClicked(MouseEvent me) {
                objects.add(me.getX() + "--" + me.getY());
                testTree.update();
                TestGUI.this.pack();
                canvas.repaint();
            }
        });
        canvas.setPreferredSize(new Dimension(400, 490));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
//        setSize(500, 500);
        setVisible(true);
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestGUI();
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM