I've created a TableCellRenderer
out of a JLabel
whose paint()
is somewhat heavy, mostly bacause of a g2d.drawString()
which is given a utf string. The problem is that this paint()
is very repeatedly called, within the following stack:
MultiTableCellRenderer$TableHeaderLabel.paint:235
CellRendererPane.paintComponent:151
BasicTableUI.paintCell:2115
BasicTableUI.paintCells:2016
BasicTableUI.paint:1812
ComponentUI.update:161
JComponent.paintComponent:780
JComponent.paint:1056
JComponent.paintChildren:889
JComponent.paint:1065
JViewport.paint:728
JComponent.paintChildren:889
JComponent.paint:1065
JComponent.paintChildren:889
JComponent.paint:1065
JComponent.paintChildren:889
JComponent.paint:1065
JComponent.paintChildren:889
JSplitPane.paintChildren:1047
JComponent.paint:1065
JComponent.paintToOffscreen:5219
RepaintManager$PaintManager.paintDoubleBuffered:1572
RepaintManager$PaintManager.paint:1495
RepaintManager.paint:1265
JComponent._paintImmediately:5167
JComponent.paintImmediately:4978
RepaintManager$4.run:824
RepaintManager$4.run:807
AccessController.doPrivileged
....
How can this repeating process be prevented? I've checked the DefaultTableCellRenderer
implementation, and saw that they have overriden many of the methods, such as repaint()
, revalidate()
etc. replacing most of them with empty methods to enhance performance. I also did so, and it did help, but yet the greater part of the problem is staying there. At least about 10% of my CPU is constantly consumed by this very paint()
method, and the entire application has been seriously slowed down. Any idea?
To understand why the paint method is invoked excessively, you can start by checking DefaultTableCellRenderer JavaDoc.
You also need to understand Swing drawing mechanism and how revalidation works.
You can read about Painting in AWT and Swing here.
A simple and efficient (performance-wise & code-wise) rule of thumb, is to extend DefaultTableCellRenderer and customize it to your needs.
Customization is usually done by overriding setValue()
or getTableCellRendererComponent()
.
It's important to note that getTableCellRendererComponent()
:
JLabel
in the case of DefaultTableCellRenderer) for drawing, revalidation and repainting.Try comparing your existing implementation and this implementation using the profiler to convince yourself that it produces much less drawing and layout events as well as a better CPU utilization.