2011-11-01 14 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以查看代碼中問題的位置。 –