所以在最近的一个回答中,有人评论了这一点(关于绘画):
“这可能是90%Swing程序员的某种疾病:当他们制作自己的组件时,他们总是扩展JPanel而不是JComponent。为什么?”
我仍然是编程新手,所以我认为现在称自己为Swing程序员为时尚早,因为我尚未找到自己的利基。但是压倒JPanel
只是我教的方式。所以我开始找到评论者“为什么?”的答案。这些是我找到的一些答案。
背景绘制是主要区别。 JComponent类不绘制其背景,因此您必须在重写的paintComponent方法中绘制背景。相比之下,JPanel有一个不透明的背景,可以通过调用它的paintComponennt方法来绘制。
一些程序员喜欢扩展JPanel类,而不是扩展JComponent。 JPanel旨在成为可以包含其他组件的容器,但也可以在其上绘制。只有一个区别。面板是不透明的,这意味着它负责绘制其边界内的所有像素。最简单的方法是使用背景颜色绘制面板,方法是在每个面板子类的paintComponent方法中调用super.paintComponent:
如果opaque属性设置为true ...则Swing绘图系统不必浪费时间尝试在组件后面进行绘制,从而提高性能。
我认为最后一句话真的解释得最好。但除了不透明之外,还有其他有益的理由“90%的Swing程序员患有这种疾病”延伸JPanel
而不是JComponent
?
答案 0 :(得分:5)
不透明度处理的差异不是唯一的因素。
查看JPanel源代码有帮助,因为它只有~100行。
所有构造函数最终都会调用此构造函数。 不透明度和双缓冲默认为true。 默认的LayoutManager是FlowLayout,您可能想要也可能不想要。
public JPanel(LayoutManager layout, boolean isDoubleBuffered) {
setLayout(layout);
setDoubleBuffered(isDoubleBuffered);
setUIProperty("opaque", Boolean.TRUE);
updateUI();
}
Loy等人在O'Reilly的Java Swing第2版中建议为真正的自定义组件扩展JComponent(p.1333),但也提到需要考虑UI委托。 JPanel处理它自己的具体AccessibleContext,而扩展JComponent的类返回null。
对于只读的可视化组件,我通常会扩展JComponent,但由于可访问性的额外考虑,我可能会对交互式组件进行三次考虑。
干杯,
答案 1 :(得分:4)
这是正确的心理。如果您检查JPanel
的来源,则不会触及不透明。然而,大多数PL& Fs的大多数版本确实设置了不透明属性。他们可以随机设置其他属性。
早期版本的GTK PL& F没有为JPanel
设置不透明度。它被改变了,显然是为了表现,尽管使用JPanel
不恰当的劣质Swing程序员可能是一个因素。
子类化JPanel
的正当理由非常少。不要这样做。