有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java优化jtable

我用一个JLabel创建了一个TableCellRenderer,它的paint()有点重,主要是因为一个g2d.drawString()被赋予了utf字符串。问题是这个paint()在以下堆栈中被反复调用:

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   
....

如何防止这种重复过程?我检查了DefaultTableCellRenderer实现,发现它们覆盖了许多方法,例如repaint()revalidate()等。用空方法替换大部分方法以提高性能。我也这么做了,这确实有所帮助,但问题的更大部分在于留在那里。我的CPU中至少有10%被这个paint()方法不断消耗,整个应用程序的速度严重降低。知道吗


共 (1) 个答案

  1. # 1 楼答案

    要理解为什么过度调用paint方法,可以从检查DefaultTableCellRendererJavaDoc开始
    您还需要了解Swing绘图机制以及重新验证的工作原理
    你可以阅读AWT和Swing here中的绘画

    一个简单而高效(性能和代码方面)的经验法则是扩展DefaultTableCellRenderer,并根据您的需要对其进行定制
    定制通常通过覆盖setValue()getTableCellRendererComponent()来完成

    需要注意的是getTableCellRendererComponent()

    1. 通常返回对自身的引用
    2. 应该而不是每次完全出于性能原因调用时创建一个新对象
    3. 充当橡皮图章,一次渲染一个所有单元
    4. 使用优化对象(在DefaultTableCellRenderer的情况下是修改的JLabel)进行绘制、重新验证和重新绘制

    试着使用profiler将您现有的实现与此实现进行比较,让自己相信它产生的绘图和布局事件要少得多,CPU利用率也更好