Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JPanel和JComponent上绘画有什么好处?_Java_Swing_Jpanel_Paint_Jcomponent - Fatal编程技术网

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

Java 在JPanel和JComponent上绘画有什么好处?,java,swing,jpanel,paint,jcomponent,Java,Swing,Jpanel,Paint,Jcomponent,因此,在最近的一次回答中,有人评论道(关于绘画): “这可能是90%的Swing程序员的某种疾病:当他们制作自己的组件时,他们总是扩展JPanel而不是JComponent。为什么?” 我对编程还是相当陌生,所以我认为现在称自己为Swing程序员还为时过早,因为我还没有找到适合自己的位置。但是重写JPanel正是我被教导的方式。所以我开始寻找评论者“为什么”问题的答案。这些是我找到的一些答案 背景绘制是主要区别。JComponent类不绘制其背景,因此必须在重写的paintComponent方

因此,在最近的一次回答中,有人评论道(关于绘画):

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

我对编程还是相当陌生,所以我认为现在称自己为Swing程序员还为时过早,因为我还没有找到适合自己的位置。但是重写
JPanel
正是我被教导的方式。所以我开始寻找评论者“为什么”问题的答案。这些是我找到的一些答案


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


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


如果不透明属性设置为true。。。这样,Swing绘制系统就不必浪费时间尝试在构件后面绘制,从而提高了性能



我认为最后一句话最能说明问题。但是除了不透明之外,还有其他有益的原因吗“90%的Swing程序员患有这种疾病”,即扩展
JPanel
,而不是
JComponent

这是正确的心理状态。如果您检查
JPanel
的源代码,它不会接触不透明。然而,大多数PL&Fs的大多数版本都设置了不透明属性。他们可以随机设置其他属性

GTK PL&F的早期版本没有为
JPanel
设置不透明性。它被改变了,显然是为了性能,尽管可能是劣质的Swing程序员不适当地使用
JPanel
可能是一个因素


子类化
JPanel
的理由很少。不要这样做。

不透明度处理的差异不是唯一的因素

查看JPanel源代码会有所帮助,因为它只有大约100行

所有构造函数最终都会调用此构造函数。 不透明度和双缓冲默认为true。 默认布局管理器是FlowLayout,您可能需要也可能不需要

public JPanel(LayoutManager layout, boolean isDoubleBuffered) {
        setLayout(layout);
        setDoubleBuffered(isDoubleBuffered);
        setUIProperty("opaque", Boolean.TRUE);
        updateUI();
}

Loy等人在O'ReLyjava的JavaSwing第二版中建议将JPUTE扩展为真正的自定义组件(P.1333),但也提到需要考虑UI委托。JPanel处理自己的具体AccessibleContext,而扩展JComponent的类返回null

对于只读可视组件,我通常会扩展JComponent,但对于交互式组件,我可能会三思而后行,因为需要额外考虑可访问性


干杯,

opaque参数与此选择无关,因为它是
JComponent
声明的方法(我假设您已经知道类层次结构中的
JPanel
)@MarkOpolnik从我所了解到的是,
JPanel
是不透明的,而
jcomont
不是。@peeskillet,另一个原因是UI委托:面板将由适当的外观UI委托装饰。在UIManger的默认设置中,有一些默认设置可用于面板,以提供一些可以贯穿应用程序生命周期的默认设计。相反,UIManger没有用于
JComponent
的组件,我还要提到的主要区别是UI委托,它负责绘制面板的背景。即使使用component.setOpaque(true)和component.setBackground(Color.RED),也不会绘制背景,因为没有UI委托进行绘制。如果希望组件尊重背景/不透明属性,则必须向paintComponent()方法添加代码以进行绘制。@MarkoTopolnik,所有Swing组件都负责绘制整个背景。这就是不透明属性的含义。如果不绘制背景,则会留下绘制瑕疵。例如,请看哪个试图解释不透明属性如何对组件起作用。+1但是,
JComponent
更一般,是子类化的正确目标,而
JPanel
太具体了,子类化只是一种攻击吗?您是否同意您的自定义组件参与PLAF框架通常没有意义?