我注意到这很常见。例如 DefaultListCellRenderer、DefaultTableCellRenderer 和 DefaultTreeCellRenderer 都使用它。我在网上看到的许多自定义单元格渲染器也使用它。我想在我的代码中使用自定义 TableCellRenderer,但我对是否真的需要继承 JLabel 感到困惑。继承 JLabel 有什么好处?
3 回答
DefaultTableCellRenderer的API状态:
table 类定义了一个单元格渲染器,并将其用作渲染表格中所有单元格的橡皮图章;它渲染第一个单元格,更改该单元格渲染器的内容,将原点移动到新位置,重新绘制它,等等。标准
JLabel
组件并非设计为以这种方式使用,我们希望避免在revalidate
每次绘制单元格时触发 a。这将大大降低性能,因为revalidate
消息将向上传递容器的层次结构以确定是否有任何其他组件会受到影响。由于渲染器仅在绘画操作的生命周期内作为父级,我们同样希望避免与遍历绘画操作的层次结构相关的开销。所以这个类覆盖了validate
,invalidate
,revalidate
,repaint
, 和firePropertyChange
方法为无操作并覆盖该isOpaque
方法只是为了提高性能。如果您编写自己的渲染器,请牢记这一性能注意事项。
JLabel 拥有他们需要的所有火力,还有一些——它处理文本和图标,它可以自行居中,默认情况下它具有非透明背景,......我可以继续......
因为每个人——甚至是早期的摇摆队——都有权偶尔以错误的方式做事:-)
扩展一个组件而不是实现渲染器接口并让该实现委托给一个组件是错误的(这可能是一个特殊实现的 JLabel,其中包含他们认为必要的所有口哨,我个人不相信)。我们都还在为那个糟糕的实施决定而苦恼——DefaultTableCellRenderer 不祥的“颜色记忆”是一个直接后果。
所以:不要子类化someComponent-to-implement-someRenderer。尤其不是 someComponent == DefaultTableCellRenderer,它坏了!
顺便说一句,SwingX 做对了 :-)