2011-11-01 26 views
5

当我从数据库中检索1000多个java对象时,它会很快完成。我最终与List<Object>匹配我的查询。JTree:从数据库检索的对象中加速绘制超过1000个子节点?

问题是将这些对象绘制到Jtree上。

例如,我有一个给定节点的parentID。当这个节点(DefaultMutableTreeNode)被双击(TreeMouseListener.class)时,它将显示该节点的直接子节点,而不是所有子节点(虽然可能稍后需要,但现在不需要)。

问题是,此jtree绘图操作需要很长时间才能完成为所选父节点添加超过1000个子项目DefaultMutableTreeNodes

EX)的new DefaultMutableTreeNode(Person person);

如何1000可这个拉丝工艺有待加快?

我没有使用任何自定义单元格渲染器,也没有显示除了每个节点的文本的小部分以外的任何内容。

+0

在[这个问题]中的一些东西(http://stackoverflow.com/questions/7893162/how-to-get-the列数和行数是可见的在我的jlist中)可能证明与你的相关。 –

+0

即时通讯作为评论,因为我不想碰它。但是我正面临缓慢的原因是因为我正在使用远程数据库服务器。当我使用本地数据库时,这个pr0oblem消失了。 – KJW

回答

-3

使用JPanel为图形编写自己的JTree:P。

也可以使一个类JTree的延伸和覆盖paint(Graphics g)方法

2

你可能创造1000+ DefaultMutableTreeNodes把你的名单,问题是创建许多对象快,转换你的对象DefaultMutableTreeNode 。如果您不创建所有这些对象,则可以提高性能。我建议你直接编写自己的TreeModel实现,它直接与你的对象模型一起工作,因此你不必重新创建那么多对象。这应该会显着提高你的速度。我已经在JTree中放入了10,000个对象(我这样做了,但它可能不是那么棒),但是我必须编写自己的TreeModel,所以我不必重新创建这些对象。

但是,与所有性能问题一样,您应该首先确定您需要花费时间和解决该问题的位置。如果事实证明是这个问题,那么你可以做到这一点。您不需要尝试创建自己的图形绘制例程,因为这比编写自己的TreeModel的工作量要多得多。

另一种选择是在需要时按需提取树。因此,当用户扩展每个节点从服务器获取子节点时,获取根。用户无论如何都无法一次查看所有1000多个节点,因此这将显着减少您通过网络传输的数量,并减少在服务器上花费的时间。

+0

所以你的意思是只创建“空”defaultmutabletreenodes? – KJW

+0

编号DefaultMutableTreeNode实现两个接口MutableTreeNode和TreeNode。从服务器发送的对象可以实现TreeNode或MutableTreeNode,而JTree可以直接使用它们而不是DefaultMutableTreeNode。您还需要创建自己的TreeModel实现者,以便为您的TreeNode/MutableTreeNode的实现提供引用。阅读关于此的javadoc,以及谷歌在网络上如何做到这一点有很多文件。 – chubbsondubs

+0

列表包含存储在对象数据库中的对象。不能存储仅实现TreeNode POJO的对象。一旦检索到列表,我应该创建另一个包含这些对象的列表?因为我不明白我如何创建一个“实施者”,而不是执行“新的DefaultMutableTreeNode(object)'....你是不是指'对象实现MutableTreeNode'并直接存储它?对困惑感到抱歉。我也在这里尝试这个方法:http://stackoverflow.com/questions/7962252/jtree-how-to-hide-parts-of-a-given-defaultmutabletreenodes-text – KJW

5

你需要时间放慢速度,但我怀疑它只是创建DefaultMutableTreeNodes应该比从数据库中加载Person对象更快。这不太可能是绘画(除非你的Person#toString()很慢),因为屏幕上不会有一千个节点。

我的猜测是你一个接一个地添加节点,导致一千个变化事件,而不是一次添加所有的孩子。您应该直接将千个子节点添加到父节点,然后在父节点上调用DefaultTreeModel#nodeStructureChanged(节点)。

如果这仍然很慢,那么是SSCCE的时候了。例如,按下我的系统上的按钮显示没有任何延迟:

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 

import javax.swing.*; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 

public class TestJTree { 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       final DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); 
       final DefaultTreeModel model = new DefaultTreeModel(root); 
       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.getContentPane().add(new JScrollPane(new JTree(model))); 
       frame.getContentPane().add(new JButton(
         new AbstractAction("Add thousand children") { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         int offset = root.getChildCount() + 1; 
         for (int i = 0; i < 1000; i++) { 
          DefaultMutableTreeNode child = new DefaultMutableTreeNode(
            "Person " + (i + offset)); 
// adding child with event (but isn't much slower really) 
//        model.insertNodeInto(child, root, root.getChildCount()); 
          root.add(child); 
         } 
         model.nodeStructureChanged(root); 
        } 
       }), BorderLayout.PAGE_END); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

如何直接添加千个子节点而不需要在循环中逐个添加它们? – KJW

+0

@ kim-jong-woo查看更新回答 –

+0

实际上用DefaultTreeModel#insertNodeInto(在SSCCE中注释掉)进行了测试,我注意不到速度上的差异。所以如果你看到你的代码有所不同,那肯定不是Swing,那就是问题所在。更好地启动VisualVM以查看代码中问题的位置。 –