本文介绍了JTree 延迟加载 展开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望你一切顺利.

我有一个 JTree,我使用数据库查询(每个节点)延迟加载它.我在屏幕上有一个按钮,当用户单击该按钮时,我在数据库中执行一些 insert/update/delete,然后将模型添加回 Jtree 中,只有 root 及其使用 SQL 的直接子节点(这会折叠树和选择,并且所有展开的节点都会折叠,这是预期的,因为它是一棵延迟加载的树)

I have a JTree which I load lazily using database query (each node). I have a button on the screen and when user clicks the button I perform some insert/update/delete in database and then add the model back in Jtree with only root and its immediate children using an SQL (this collapses the tree and selection and all expanded nodes collapse which is expected since it is a lazily loaded tree)

我想要完成的是在用户单击按钮以insert/update/delete 之前,我读取所有展开状态并将其保存在内存中,然后当我重新初始化 JTree 我遍历那些扩展的子节点并调用 jtree.expandPath 但它没有扩展节点 :(.

What I want to accomplish is before user clicks button to insert/update/delete, I read all the expanded state and save it in memory then when I re-initialize the JTree I loop through those expanded children and call jtree.expandPath but it does not expand the nodes :(.

我什至添加了一个 TreeWillExpandListener 并且在 treeWillExpand 事件中我添加了代码来从数据库中获取节点的子节点,我看到查询确实被执行以获取子节点但是 JTree 仍然显示为折​​叠状态.

I even added a TreeWillExpandListener and in treeWillExpand event I added code to get the children of the node from database and I see that query does get executed to get the childreen but JTree still shows up as collapsed.

我真的需要你的帮助.请指教.这是代码片段.

I really need your help. Please advise. Here is the code snippet.

package marketdatagui;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.EventListenerList;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.io.File;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;


public class StressGroupModel
    implements TreeModel,Serializable, Cloneable
{
    protected EventListenerList listeners;

    private static final Object LEAF = new Serializable() { };

    private Map map;

    private NodeData root;

    private class NodeData{
        String id;
        String name;

        public String toString(){
            return name;
        }
    }

    public StressGroupModel()
    {
        this.root = new NodeData();
        root.id = "Root";
        root.name = "Root";

        this.listeners = new EventListenerList();

        this.map = new HashMap();

        List rootChildren = new ArrayList();

        NodeData d1 = new NodeData();
        d1.id = "5000007";
        d1.name = "Name5000007";

        rootChildren.add(d1);

        NodeData d2 = new NodeData();
        d2.id = "10000054";
        d2.name = "Name10000054";

        rootChildren.add(d2);
        map.put(root.id, rootChildren);
    }


    public Object getRoot()
    {
        return root;
    }

    public boolean isLeaf(Object node)
    {
        return map.get(node) == LEAF;
    }

    public int getChildCount(Object node)
    {
        List children = children(node);

        if (children == null)
            return 0;

        return children.size();
    }

    public Object getChild(Object parent, int index)
    {
        return children(parent).get(index);
    }

    public int getIndexOfChild(Object parent, Object child)
    {
        return children(parent).indexOf(child);
    }

    protected List children(Object node)
    {
        NodeData s = (NodeData)node;

        Object value = map.get(s.id);

        if (value == LEAF)
            return null;

        List children = (List)value;

        if (!"Root".equals(s.id))
        {
            String[][] dbData = getChildren(s.id);

            if (dbData != null)
            {
                children = new ArrayList(dbData.length);
                for (int i = 0; i < dbData.length; i++)
                {
                    NodeData d = new NodeData();
                    d.id = dbData[i][1];
                    d.name = dbData[i][1] + "Name";
                    children.add(d);
                    if ("R".equals(dbData[i][2]))
                        map.put(d, LEAF);
                }
            }
            else
                children = new ArrayList(0);

            map.put(s.id, children);       
        }

        return children;
    }

    private String[][] getChildren(String parent_uid){
        String sql = "select parent_uid,child_uid,child_type from stress_groups_mapping "
              + " where parent_uid="+ parent_uid
              +" order by parent_uid, child_uid";

        return Util.getTableData(sql);
    }

    public void valueForPathChanged(TreePath path, Object value)
    {
    }

    public void addTreeModelListener(TreeModelListener l)
    {
        listeners.add(TreeModelListener.class, l);
    }

    public void removeTreeModelListener(TreeModelListener l)
    {
        listeners.remove(TreeModelListener.class, l);
    }

    public Object clone()
    {
        try
        {
            StressGroupModel clone = (StressGroupModel)super.clone();

            clone.listeners = new EventListenerList();

            clone.map = new HashMap(map);

            return clone;
        }
        catch (CloneNotSupportedException e)
        {
            throw new InternalError();
        }
    }

}

  • 这是我创建树的方法
  • 公共创建树{

    JFrame f = new JFrame("Tree Dragging Tester");
              DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Object());
              jtree = new JTree(new StressGroupModel());
              TreeWillExpandListener treeWillExpandListener = new TreeWillExpandListener() {
                    public void treeWillCollapse(TreeExpansionEvent treeExpansionEvent)
                        throws ExpandVetoException {
    
    
                    }
    
                    public void treeWillExpand(TreeExpansionEvent treeExpansionEvent) throws ExpandVetoException {
                        TreePath path = treeExpansionEvent.getPath();
                        Object node =  path.getLastPathComponent();
                        ((StressGroupModel)jtree.getModel()).getChildCount(node);
                      }
    
    
              };
    
              jtree.addTreeWillExpandListener(treeWillExpandListener);
    
              f.getContentPane().add(jtree, BorderLayout.CENTER);
              f.setSize(300, 200);
              f.setVisible(true);
    }
    

    • 这是我保存展开状态的方法
    • 枚举路径 = jtree.getExpandedDescendants(newTreePath(jtree.getModel().getRoot()));

      • 插入/更新/删除数据库内容
      • 现在重新初始化模型并添加回 JTree(因此它选择最新的来自数据库的值)
      • 现在我循环并调用 expand 来扩展用户扩展的节点在他点击按钮之前,但遗憾的是它一直处于折叠状态:(
      • jtree.setModel(new StressGroupModel());而 (paths.hasMoreElements()) {

                    TreePath treePath = (TreePath) paths.nextElement();
        
                    try {
        
                    jtree.expandPath(treePath);
                    jtree.setSelectionPath(treePath);
        
                    }
                    catch(Exception ex){
        
                    }
        
                }
        

        推荐答案

        我找到了解决方案.

        在我的 NodeData 类中需要一个 equals 方法和 hashCode,问题是在我尝试扩展路径时设置新模型后内部出现的,equals 返回 false 作为 equals 的默认实现执行浅比较",即只比较引用,我不得不重写 hashCode 和 equals 方法,并在 equals 方法中进行了深度比较".

        Need an equals method and hashCode in my NodeData class, problem was internally after setting the new Model when I was trying to expand the path the equals returned false as default implementation of equals does a "shallow compare" i.e. only compares references, I had to override the hashCode and equals method and did a "Deep compare" in equals method.

        谢谢

        这篇关于JTree 延迟加载 展开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 23:27