Swing JTable: Mein CellRenderer ist ein Performance-Killer?

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
Hi Leute,

ich hab ein Problem mit meinen CellRenderern. Wenn ich keine eigenen installiere, sondern die defaultmässigen lasse, dann funzt alles wunderbar: Ich kann meinen 6-spaltigen Table maximieren und zB eine Spalte anpacken und wild damit rumfuchteln: Gefühlte 100 fps :toll:

So, sobald ich den 6 Spalten nun meinen eigenen CellRenderer verpasse, und den gleichen Test mache, ruckelt alles extrem stark, d.h. beim Rumspielen mit einer gepackten Column sinken die repaints auf gefühlte 10fps oder weniger. Was mich etwas schockt, denn ich habe inzwischen schon alles soweit minimiert wie es nur geht. Scheinbar ist schon die Klasse, die ich verwende falsch?! (JLabel)

Hier mein "Killer"-Renderer :lol:
Java:
public class TableTextRenderer extends JLabel implements TableCellRenderer {	
	public TableTextRenderer() {
	}

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

		setText(value == null ? "" : value.toString());
		return this;
	}
}

Ich meine was kann ich denn hier bitteschön falsch machen, ich hab nur 1 Zeile Code 😱

Es muss wohl am JLabel liegen? Wie zum Teufel schaut denn bitte der default-mässige Renderer aus? Ich bitte um Hilfe...

edit: Fals ich hier schon was falsch mache, ich adde in meinem Table-Constructor die Renderer wie folgt:

Java:
	/* install cell renderer */
		for (int i = 0; i < getColumnCount(); i++) {
			TableCellRenderer r = new TableTextRenderer();
			TableColumn col = getColumnModel().getColumn(i);
			col.setCellRenderer(r);
		}

edit2: Mit nem JPAnel hab ichs auch grad versucht, das macht es auch nicht schneller.
 
Zuletzt bearbeitet:
schau dir mal die Implementierung von DefaultTableCellRenderer an, der auch von JLabel erbt, bzw. die API-Beschreibung der überschriebenden Methoden sowie insbesondere
Implementation Note: This class inherits from JLabel, a standard component class. However JTable employs a unique mechanism for rendering its cells and therefore requires some slightly modified behavior from its cell renderer. The table class defines a single cell renderer and uses it as a as a rubber-stamp for rendering all cells in the table; it renders the first cell, changes the contents of that cell renderer, shifts the origin to the new location, re-draws it, and so on. The standard JLabel component was not designed to be used this way and we want to avoid triggering a revalidate each time the cell is drawn. This would greatly decrease performance because the revalidate message would be passed up the hierarchy of the container to determine whether any other components would be affected. As the renderer is only parented for the lifetime of a painting operation we similarly want to avoid the overhead associated with walking the hierarchy for painting operations. So this class overrides the validate, invalidate, revalidate, repaint, and firePropertyChange methods to be no-ops and override the isOpaque method solely to improve performance. If you write your own renderer, please keep this performance consideration in mind.
DefaultTableCellRenderer (Java Platform SE 6)


dass es soviel ausmacht ist mir allerdings noch nicht aufgefallen,
vielleicht wäre der Effekt schon gemindert, wenn du nicht für jede Column einen eigenen Renderer nimmst,
sondern nur einen für alle,
überschriebenene Methoden sind aber gewiss noch besser
 
Zuletzt bearbeitet von einem Moderator:
Jup, wenn du in dieser Methode neue Components instanzierst stirbst du den Performance-Tot. Instanziere einen, und fülle dessen Text/Parameter immer neu. Swing platziert die Renderer nicht als physikalische Widgets, sondern ruft deren paint Methode im Kontext des eigenen Graphics Objekt auf.
 
also
/* install cell renderer */
wird doch bestimmt nur einmal ausgeführt, dafür aber ein Renderer pro Column, statt einer insgesamt,
ansonsten verwendet aber der TableTextRenderer sich selbst als JLabel, und 'setzt dessen Text/Parameter immer neu', nicht anders als der DefaultTableCellRenderer?

bei den nicht überschriebenen paint-Methoden, die das ganze verlangsamen, werden aber sicherlich zahllose Objekte umsonst erzeugt,
im allgemeinen unnötigen Aufwand
 
Also ich hab jetzt die Adapter-Methoden erzeugt die auch der DefaultRenderer nutzt, und siehe da es läuft perfekt!

Ich werde jetzt auch nur noch einen Renderer erzeugen, statt für jede Spalte einen eigenen. Ich wusste gar nicht dass das so geht.. Aber ne Verständnisfrage: Wäre es nicht trotzdem egal? Ich meine dann hab ich halt 5 solcher Renderer statt nur einen, ob jetzt quasi die paint-Methode von einem einzigen 5 mal aufgerufen wird, oder von 5 verschiedenen jeweisl einmal... Sollte doch keinen Unterschied machen oder?

Auf jeden Fall funzt es jetzt wunderprächtig 😀

Aber eine Frage noch: Ich hab mich gefragt ob sowas ähnliches auch für den HeaderRenderer gilt, denn da hab ich auch nen eigenen. Sysout sagt mir der defaultmässige HeaderRenderer ist ein "DefaultTableCellHeaderRenderer", aber in der API gibt es die Klasse nicht :autsch: Ist die privat? Also in der Beschreibung der Klasse JTableHeader steht zumindest nix.
Aber wisst ihr da mehr?

Ansonsten dickes Dankeschön :toll:
 
> ob jetzt quasi die paint-Methode von einem einzigen 5 mal aufgerufen wird, oder von 5 verschiedenen jeweisl einmal... Sollte doch keinen Unterschied machen oder?

wenn die Hintergrundprozesse ausgeschaltet sind, ja dann könnte das praktisch egal sein,
ich meinte, dass das bei nicht-überschriebenen repaint & Co. vielleicht noch zusätzlich Probleme macht,

ganz grob fantasiert:
wenn das JLabel etwa intern eh drauf achtet, dass es nicht mehr als 30x pro Sekunde schwer Arbeit macht um die Performance zu senken,
dann wäre ein solch unnötiges JLabel nicht ganz so schlimm wie 15 derartige JLabel bei 15 Columns
 
der Header ist glaube ich nur im Look & Feel oder wer weiß was, ach ich weiß nix
Lol wenn schon von dir so ein Satz kommt dann will ich damit nix zu tun haben 😉 Funzt ja jetzt auch supergut. Danke nochmal an alle
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben