【问题标题】:How to populate hierarchical Jtree from Mysql如何从 Mysql 填充分层 Jtree
【发布时间】:2022-01-29 12:44:10
【问题描述】:

我有这个 MySQL 表

+---------------------------------------------------------------------------------------+
itemCat_id | itemCat_name | itemCat_description | itemCat_parent_id | itemCat_icon_path
+---------------------------------------------------------------------------------------+
1          |Juice & Water | null                |0                  | null 
2          |Tools         | null                |0                  | null 
3          |Cleaning Supp.| null                |0                  | null 
4          |Snack         | null                |0                  | null 
5          |Cosmetics     | null                |0                  | null 
0          |CATEGORIES    | null                | null              | null 
6          |Shampoo       | null                |5                  | null  
7          |Water         | null                |1                  | null  
+---------------------------------------------------------------------------------------+

我希望每个父节点都有自己的子节点, 并且具有null 父ID 的那个是根。 但是我编写的代码将根填充为唯一的父级。

代码如下:

 invItemsJtree.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
 invItemsJtree.setModel(fillTree());
 invTreeScrollPane.setColumnHeaderView(invItemsJtree);
 
 public DefaultTreeModel fillTree(){
        
    DefaultTreeModel dtm = null;
    try {
                
        String query = "SELECT itemCat.itemCat_id, itemCat.itemCat_name, itemCat.itemCat_description,"
                    + "itemCat.itemCat_parent_id, itemCat.itemCat_icon_path FROM itemCat ";
                        
        pst = conn.prepareStatement(query);
        rs = pst.executeQuery();
                
        int rowCount = 0; 
        int i = 0;   
        int j = 0;   
        while(rs.next()){
            rowCount++;
        }
        rs = pst.executeQuery();
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Accounts Tree");
        String[] nodeID = new String[rowCount];
        String[] parentID = new String[rowCount];
        DefaultMutableTreeNode[] node = new DefaultMutableTreeNode[rowCount];
        while(rs.next()){
        node[i] = new DefaultMutableTreeNode(rs.getString("itemCat_name"));
        parentID[i] = rs.getString("itemCat_parent_id");
        nodeID[i]= rs.getString("itemCat_id");
        rootNode.add(node[i]);    
        i++;               
        }
        for (i = 0; i < rowCount; i++) {
            for (j = 0; j < rowCount; j++) {
                if (/*!"0".equals(node[i]) &&*/ parentID[j]== nodeID[i]) {
                    node[i] = new DefaultMutableTreeNode(rs.getString("itemCat_name"));
                    parentID[i] = rs.getString("itemCat_parent_id");
                    nodeID[i]= rs.getString("itemCat_id");
                    node[i].add(node[j]);
                }
            }
        }
        dtm = new DefaultTreeModel(rootNode);
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex.getStackTrace(), "ERROR", JOptionPane.ERROR_MESSAGE);
        } finally {
        try {
            pst.close();
            rs.close();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex.getStackTrace(), "ERROR", JOptionPane.ERROR_MESSAGE);
        }

    } 
        return dtm;
}

我该如何解决? 如果在我的情况下有用,我该如何使用哈希映射?

【问题讨论】:

  • 对mysql中引入的使用递归cte 8 else树在mysql中变得棘手
  • 在 MySQL 8 之前的版本上使用迭代存储过程。
  • 我想用java代码制作

标签: java mysql swing jtree


【解决方案1】:

简介

Oracle 有一个有用的教程,Creating a GUI With Swing。跳过“使用 NetBeans IDE 学习”部分。

您正在尝试用一种方法完成所有工作。将您的代码分解为简单的方法和类。一个方法应该做一件事,并且代码不超过 20 行。这样,您无需滚动即可在屏幕上看到整个方法。

说明

当我创建 Swing GUI 时,我使用 model–view–controller (MVC) 模式。这种模式使我能够分离我的关注点并一次专注于 Swing 应用程序的一个部分。

这是我用来测试代码的简单 GUI 的图像。

型号

我创建了两个模型类。 Category 类包含与 MySQL 数据库表的一行相同的信息。

public class Category {

    private final int id;
    
    private final Integer parentId;

    private final BufferedImage icon;

    private final String description, name;

    public Category(int id, String name, String description, Integer parentId, 
            BufferedImage icon) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.parentId = parentId;
        this.icon = icon;
    }

    public int getId() {
        return id;
    }

    public Integer getParentId() {
        return parentId;
    }

    public BufferedImage getIcon() {
        return icon;
    }

    public String getDescription() {
        return description;
    }

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

}

JTreeModel 类构造了JTree 模型。这是迭代代码。对于每个级别,您都需要在 createTreeModel 方法中添加一个 for 循环来查找叶子。

createTreeModelmethod 应该是递归方法,但我无法编写代码使其递归。如果其他人可以创建递归方法,那将是一个很好的例子。查看代码,您可以了解为什么人们建议使用 MySQL 递归。

public class JTreeModel {
    
    private final DefaultMutableTreeNode rootNode;
    
    public JTreeModel() {
        List<Category> categoryList = readSQLTable();
        this.rootNode = createTreeModel(categoryList);
    }

    private List<Category> readSQLTable() {
        //
        // Here's where you read the MySQL table into a List.
        // I'd create a separate SQL class to handle all SQL.
        //
        // I'm just going to hard code the information for the example
        //
        List<Category> categoryList = new ArrayList<>();
        categoryList.add(new Category(1, "Juice & Water", null, 0, null));
        categoryList.add(new Category(2, "Tools", null, 0, null));
        categoryList.add(new Category(3, "Cleaning Supp.", null, 0, null));
        categoryList.add(new Category(4, "Snack", null, 0, null));
        categoryList.add(new Category(5, "Cosmetics", null, 0, null));
        categoryList.add(new Category(0, "CATEGORIES", null, null, null));
        categoryList.add(new Category(6, "Shampoo", null, 5, null));
        categoryList.add(new Category(7, "Water", null, 1, null));
        
        return categoryList;
    }
    
    private DefaultMutableTreeNode createTreeModel(
            List<Category> categoryList) {
        DefaultMutableTreeNode rootNode = 
                new DefaultMutableTreeNode("Accounts Tree");
        
        // First, find the root
        Category rootCategory = getRoot(categoryList);
        DefaultMutableTreeNode categoryNode = 
                new DefaultMutableTreeNode(rootCategory);
        rootNode.add(categoryNode);
        
        // Next, find the leaves;
        List<DefaultMutableTreeNode> leafNodes = addLeaves(
                categoryList, categoryNode);
        for (DefaultMutableTreeNode leafNode : leafNodes) {
            addLeaves(categoryList, leafNode);
        }
        
        return rootNode;
    }
    
    private List<DefaultMutableTreeNode> addLeaves(List<Category> categoryList, 
            DefaultMutableTreeNode rootNode) {
        List<DefaultMutableTreeNode> nodeList = new ArrayList<>();
        Category rootCategory = (Category) rootNode.getUserObject();
        int rootId = rootCategory.getId();
        
        List<Category> leafList = getLeaves(categoryList, rootId);
        for (Category category : leafList) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(category);
            nodeList.add(node);
            rootNode.add(node);
        }
        
        return nodeList;
    }
    
    private Category getRoot(List<Category> categoryList) {
        Category rootCategory = null;
        
        for (Category category : categoryList) {
            if (category.getParentId() == null) {
                rootCategory = category;
                break;
            }
        }
        
        return rootCategory;
    }
    
    private List<Category> getLeaves(List<Category> categoryList, int parentId) {
        List<Category> leafList = new ArrayList<>();
        
        for (Category category : categoryList) {
            Integer testParentId = category.getParentId();
            if (testParentId != null && testParentId == parentId) {
                leafList.add(category);
            }
        }
        
        return leafList;
    }

    public DefaultMutableTreeNode getRootNode() {
        return rootNode;
    }
    
}

代码

这是完整的可运行代码。我将所有额外的类都设为内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;

public class JTreeExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new JTreeExample());
    }
    
    private final JTreeModel model;
    
    public JTreeExample() {
        this.model = new JTreeModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("JTree Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JTree tree = new JTree(model.getRootNode());
        for (int index = 0; index < tree.getRowCount(); index++) {
            tree.expandRow(index);
        }
        
        JScrollPane scrollPane = new JScrollPane(tree);
        panel.add(scrollPane, BorderLayout.CENTER);
        
        return panel;
    }
    
    public class JTreeModel {
        
        private final DefaultMutableTreeNode rootNode;
        
        public JTreeModel() {
            List<Category> categoryList = readSQLTable();
            this.rootNode = createTreeModel(categoryList);
        }

        private List<Category> readSQLTable() {
            //
            // Here's where you read the MySQL table into a List.
            // I'd create a separate SQL class to handle all SQL.
            //
            // I'm just going to hard code the information for the example
            //
            List<Category> categoryList = new ArrayList<>();
            categoryList.add(new Category(1, "Juice & Water", null, 0, null));
            categoryList.add(new Category(2, "Tools", null, 0, null));
            categoryList.add(new Category(3, "Cleaning Supp.", null, 0, null));
            categoryList.add(new Category(4, "Snack", null, 0, null));
            categoryList.add(new Category(5, "Cosmetics", null, 0, null));
            categoryList.add(new Category(0, "CATEGORIES", null, null, null));
            categoryList.add(new Category(6, "Shampoo", null, 5, null));
            categoryList.add(new Category(7, "Water", null, 1, null));
            
            return categoryList;
        }
        
        private DefaultMutableTreeNode createTreeModel(
                List<Category> categoryList) {
            DefaultMutableTreeNode rootNode = 
                    new DefaultMutableTreeNode("Accounts Tree");
            
            // First, find the root
            Category rootCategory = getRoot(categoryList);
            DefaultMutableTreeNode categoryNode = 
                    new DefaultMutableTreeNode(rootCategory);
            rootNode.add(categoryNode);
            
            // Next, find the leaves;
            List<DefaultMutableTreeNode> leafNodes = addLeaves(
                    categoryList, categoryNode);
            for (DefaultMutableTreeNode leafNode : leafNodes) {
                addLeaves(categoryList, leafNode);
            }
            
            return rootNode;
        }
        
        private List<DefaultMutableTreeNode> addLeaves(List<Category> categoryList, 
                DefaultMutableTreeNode rootNode) {
            List<DefaultMutableTreeNode> nodeList = new ArrayList<>();
            Category rootCategory = (Category) rootNode.getUserObject();
            int rootId = rootCategory.getId();
            
            List<Category> leafList = getLeaves(categoryList, rootId);
            for (Category category : leafList) {
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(category);
                nodeList.add(node);
                rootNode.add(node);
            }
            
            return nodeList;
        }
        
        private Category getRoot(List<Category> categoryList) {
            Category rootCategory = null;
            
            for (Category category : categoryList) {
                if (category.getParentId() == null) {
                    rootCategory = category;
                    break;
                }
            }
            
            return rootCategory;
        }
        
        private List<Category> getLeaves(List<Category> categoryList, int parentId) {
            List<Category> leafList = new ArrayList<>();
            
            for (Category category : categoryList) {
                Integer testParentId = category.getParentId();
//              System.out.println(parentId + " " + testParentId);
                if (testParentId != null && testParentId == parentId) {
                    leafList.add(category);
                }
            }
            
            return leafList;
        }

        public DefaultMutableTreeNode getRootNode() {
            return rootNode;
        }
        
    }
    
    public class Category {

        private final int id;
        
        private final Integer parentId;

        private final BufferedImage icon;

        private final String description, name;

        public Category(int id, String name, String description, Integer parentId, 
                BufferedImage icon) {
            this.id = id;
            this.name = name;
            this.description = description;
            this.parentId = parentId;
            this.icon = icon;
        }

        public int getId() {
            return id;
        }

        public Integer getParentId() {
            return parentId;
        }

        public BufferedImage getIcon() {
            return icon;
        }

        public String getDescription() {
            return description;
        }

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

    }

}

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 2011-07-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2018-02-04
    • 2021-12-22
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多