2011-11-01 5 views
5

Quando recupero più di 1000 oggetti java dal database, viene eseguito molto rapidamente. Finisco con List<Object> corrispondente alla mia query.JTree: velocizza il disegno di oltre 1000 nodi figli da oggetti recuperati dal database?

Il problema è il disegno di questi oggetti su Jtree.

Ad esempio, ho un parentID di un dato nodo. Quando si fa doppio clic su questo nodo (DefaultMutableTreeNode) (TreeMouseListener.class), verranno visualizzati i figli diretti di questo nodo, non tutti i discendenti (anche se ciò potrebbe essere richiesto in seguito, se possibile, ma non in questo momento).

Il problema è che questa operazione di disegno jtree richiede molto tempo per completare l'aggiunta di 1000+ bambini DefaultMutableTreeNodes per il nodo principale selezionato.

ex) 1000 new DefaultMutableTreeNode(Person person);

Come può questo processo di disegno essere accelerato?

Non sto utilizzando alcun renderer di celle personalizzato né sto visualizzando nulla di diverso da piccoli bit di testo per ogni nodo.

+0

Alcune delle cose in [questa domanda] (http://stackoverflow.com/questions/7893162/how-to-get-the -numero-di-colonne-e-righe-che-sono-visibili-in-mio-jlist) potrebbe rivelarsi rilevante per il tuo. –

+0

im scrivendo questo come commento come non voglio batterlo. ma il motivo per cui stavo affrontando la lentezza era perché stavo usando un server di database remoto. quando ho usato il database locale, il pr0oblem era sparito. – KJW

risposta

-3

Scrivi il tuo JTree utilizzando JPanel per la grafica: P.

Oppure si può fare una classe che estende JTree e sovrascrivere il metodo di paint(Graphics g)

2

Probabilmente stai creando 1000+ DefaultMutableTreeNodes per mettere la vostra lista. Il problema è la creazione che molti oggetti in modo rapido, e traducendo gli oggetti a DefaultMutableTreeNode . Se non crei tutti questi oggetti, puoi migliorare le tue prestazioni. Ti suggerirei di scrivere la tua implementazione di TreeModel che funziona direttamente con il tuo modello di oggetti in modo da non doverli ricreare più volte. Questo dovrebbe migliorare la tua velocità in modo drammatico. Ho già creato 10.000 oggetti in JTree (l'ho fatto, ma probabilmente non era un'idea grandiosa), ma ho dovuto scrivere il mio TreeModel personale in modo da non dover ricreare quegli oggetti.

Tuttavia, come per tutti i problemi relativi alle prestazioni, è opportuno analizzarlo innanzitutto per capire dove si trascorre il tempo e risolvere il problema. Se si scopre che questo è il problema, puoi farlo. Non è necessario provare e creare le proprie routine di disegno grafico perché è molto più lavoro che scrivere il proprio TreeModel.

Un'altra opzione è quella di recuperare l'albero su richiesta in base alle esigenze. Quindi recupera la radice, quindi, mentre l'utente espande ogni nodo, preleva i suoi figli dal server. L'utente non può guardare tutti i nodi 1000+ contemporaneamente in ogni caso, quindi questo ridurrà drasticamente la quantità che si sta trasferendo sulla rete e meno tempo speso sul server.

+0

quindi intendi semplicemente creare "vuoti" defaultmutabletreenodes? – KJW

+0

No. DefaultMutableTreeNode implementa due interfacce MutableTreeNode e TreeNode. Gli oggetti che vengono inviati dal server possono implementare TreeNode o MutableTreeNode e JTree può utilizzarli direttamente invece di DefaultMutableTreeNode. Dovrai creare il tuo implementatore di TreeModel per distribuire i riferimenti alle implementazioni di TreeNode/MutableTreeNode. Leggi la javadoc su questo, e google sul web come fare questo ci sono un sacco di documenti là fuori. – chubbsondubs

+0

lista contiene oggetti memorizzati nel database degli oggetti. non è possibile memorizzare oggetti che implementano solo TreeJode POJO. Una volta recuperato l'elenco , dovrei creare un altro elenco contenente tali oggetti? perché non capisco come posso creare un "implementatore" al volo se non facendo 'new DefaultMutableTreeNode (object)' .... intendi 'object implementa MutableTreeNode' e lo memorizzi direttamente? dispiace per la confusione. Sto anche provando questo metodo qui: http://stackoverflow.com/questions/7962252/jtree-how-to-hide-parts-of-a-given-defaultmutabletreenodes-text – KJW

5

Avrete bisogno di tempo in cui il rallentamento è, ma dubito che sia solo la creazione di DefaultMutableTreeNodes che dovrebbe essere più veloce del caricamento degli oggetti Person dal database. È improbabile che sia il dipinto (a meno che il tuo Person # toString() sia molto lento) poiché non ci saranno mille nodi sullo schermo.

La mia ipotesi è che si aggiungono i nodi uno alla volta, causando un migliaio di eventi di modifica invece di aggiungere tutti i bambini contemporaneamente. È necessario aggiungere i mille nodi figlio al nodo padre direttamente e quindi chiamare DefaultTreeModel # nodeStructureChanged (nodo) sul nodo padre.

Se è ancora lento, è l'ora di un SSCCE.Ad esempio, premendo il pulsante sul mio sistema non mostra alcun ritardo a tutti:

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

come aggiungerebbe direttamente migliaia di nodi figlio senza aggiungerli uno alla volta in un ciclo? – KJW

+0

@ kim-jong-woo vedere risposta aggiornata –

+0

Testato con DefaultTreeModel # insertNodeInto (commentato in SSCCE) e non riesco a notare una differenza di velocità. Quindi se vedi una differenza nel tuo codice, non è sicuramente Swing il problema. Meglio attivare VisualVM per vedere dove si trova il problema nel codice. –

Problemi correlati