2010-12-27 7 views
3

// newbie FrageWarum läuft mein JTable CellRenderer die ganze Zeit?

Ich habe eine JTable mit einem fast grundlegenden CellRenderer (es färbt die Zeile unterschiedlich). Ich habe bemerkt, dass mein CellRenderer ständig für die Zeilen läuft, die auf dem Bildschirm angezeigt werden, auch wenn ich nichts mit der Tabelle mache.

Soll das so sein? Sollte es nicht jede Zelle einmal gerendert haben, und das ist es? Wie kann ich es stoppen und nur bei Änderung neu berechnen?

public Component getTableCellRendererComponent(JTable table, Object value, 
    boolean isSelected, boolean hasFocus, int row, int column) { 

    log.debug("Building cell : " + row + "," + column); 

    Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

    Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION.getIndex()); 
    comp.setBackground(filter.getColor()); 
    return comp; 

    } 
+1

Dies ist nicht korrektes Verhalten. Können Sie ein eigenständiges Codebeispiel erstellen, das dies demonstriert? Es wird uns helfen, dieses Problem zu beheben. –

+0

@Steve Ich denke, es wird zu viel Code sein. Ich habe gerade herausgefunden, dass ich einen anderen Renderer für bestimmte Zellen in der Tabelle habe. Kann es sein, dass sie sich gegenseitig feuern? – Yossale

+0

Es könnte alles sein. Psychisches Debugging ist schwierig. Nur eine Hauptmethode, die einen JFrame erstellt, eine Tabelle hinzufügt, einen Zellenrenderer wie den bereits gezeigten setzt - und das gleiche Problem hat. –

Antwort

1

Ich habe eine Los mit JTables mit einem Los von Daten gearbeitet. Mehr als das, was 99,9% der Java-Programmierer normalerweise manipulieren. Es gibt eine Sache, die Sie wissen müssen: Standardmäßig gibt es eine wahnsinnige Menge an Abfall, die erzeugt wird, und eine wahnsinnige Menge von typischerweise unnötiger Operation.

Wenn Sie nach schnellen und effizienten JTables sind, dann gibt es die maßgebliche Sun Artikel zum Thema:

„Weihnachtsbaum-Anwendungen, wie häufig aktualisierte JTables erstellen, die eine gute Leistung“

Beachten Sie die „die eine gute Leistung“ im Titel, da standardmäßig JTable perfs sind wirklich, wirklich erbärmlich schlecht:

Original Link (Sun)

Current link (Oracle)

Archived Version:

in diesem Artikel adviced zwei oder drei der Techniken Nach der Implementierung werden Sie erstaunliche Speedup in Ihrem JTable Rendering bemerken und Sie werden feststellen, dass viel weniger Müll erzeugt wird (und daher muss der GC weniger oft einsteigen).

+0

Es wurde ein Archivlink für die ChristmasTree-Seite hinzugefügt, da der ursprüngliche Link nicht mehr vorhanden war. Es wird erscheinen, nachdem meine Bearbeitung überprüft wurde. – bohney

+0

_JTable Perfs sind wirklich, wirklich pathetisch schlecht_ Wenn das wahr wäre, würde die Befolgung der schlechten (für Produktionscode) Malerei Abkürzungen in dem Artikel nicht viel ändern: es verbessert sich nicht einmal um eine Größenordnung;) – kleopatra

0

der Renderer bereits Caches gerenderte Komponente, wenn sich nichts ändert nichts

jedoch erneut gerendert wird, wenn der Tisch erkennt könnte etwas geändert haben es wird ein erneutes Rendern anfordern. Das Ereignis, das es am meisten auslöst, ist eine Mausbewegung.

Also ja sein normales Verhalten für eine JTable.

+0

Das dachte ich mir, aber es ist nicht was passiert: wenn der Tisch auf dem Bildschirm ist und sich die Maus nicht bewegt , Ich sehe immer noch meine Log-Nachrichten wie verrückt laufen – Yossale

+0

es ist "normal", weil die Standard-JTable-Implementierung wirklich schlecht ist. Der Artikel, den ich verlinkt habe, erklärt, wie man für häufig aktualisierte JTables sowohl normales als auch schnelles Verhalten erhält. – SyntaxT3rr0r

+1

Es ist NICHT normal, dass der Renderer ständig aufgerufen wird, wenn der Benutzer nichts mit der Maus oder der Tabelle macht. Sie haben etwas Code in Ihrem Programm, das Schleifen oder etwas sein muss. Veröffentlichen Sie Ihre SSCCE (http://sscce.org), die das Problem veranschaulicht. – camickr

1

Ich bemerke, dass Sie das Aussehen einer Zelle basierend auf dem Wert einer anderen Zelle ändern. Wenn diese Beziehung in beide Richtungen geht - Zelle 1 Aussehen basiert auf Zelle 2 und umgekehrt können Sie ein solches Problem bekommen. Aber wir brauchen ein eigenständiges Codebeispiel, das das Problem reproduziert - sonst können wir nur im Dunkeln drehen.

3

@Steve McLeods Angebot Nächstes begann ich mit dem gleichen Fehler ein Beispiel-Code erstellen, und erst dann wurde mir klar, innerhalb eines meiner CellRenderers dass

@Override 
    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 

     log.debug("Building a list for " + row + "," + column); 
     setListData(((Vector<String>)value).toArray());  
     setToolTipText("This is a tool tip for " + row + "," + column); 

     table.setRowHeight(row, Math.max(1, getPreferredSize().height)); 
     Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION_RESULT.getIndex()); 
     setBackground(filter.getColor());  
     return this; 
    } 

ich die Linie hatte:

table.setRowHeight(row, Math.max(1, getPreferredSize().height)); 

und es änderte ständig die Zeilenlinie, während die anderen Renderer in der gleichen Zeile das gleiche taten ... so feuerten sie ständig gegenseitig.