在JPanel和JComponent上绘画有什么好处?

时间:2013-12-26 16:18:17

标签: java swing jpanel paint jcomponent

所以在最近的一个回答中,有人评论了这一点(关于绘画):

  

“这可能是90%Swing程序员的某种疾病:当他们制作自己的组件时,他们总是扩展JPanel而不是JComponent。为什么?”

我仍然是编程新手,所以我认为现在称自己为Swing程序员为时尚早,因为我尚未找到自己的利基。但是压倒JPanel只是我教的方式。所以我开始找到评论者“为什么?”的答案。这些是我找到的一些答案。


  

背景绘制是主要区别。 JComponent类不绘制其背景,因此您必须在重写的paintComponent方法中绘制背景。相比之下,JPanel有一个不透明的背景,可以通过调用它的paintComponennt方法来绘制。


  

一些程序员喜欢扩展JPanel类,而不是扩展JComponent。 JPanel旨在成为可以包含其他组件的容器,但也可以在其上绘制。只有一个区别。面板是不透明的,这意味着它负责绘制其边界内的所有像素。最简单的方法是使用背景颜色绘制面板,方法是在每个面板子类的paintComponent方法中调用super.paintComponent:


  

如果opaque属性设置为true ...则Swing绘图系统不必浪费时间尝试在组件后面进行绘制,从而提高性能。


我认为最后一句话真的解释得最好。但除了不透明之外,还有其他有益的理由“90%的Swing程序员患有这种疾病”延伸JPanel而不是JComponent

2 个答案:

答案 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的正当理由非常少。不要这样做。