Java 关注JPanel:paintcomponent()的功能
您好,我是java编程新手,需要有人向我解释以下几行代码:Java 关注JPanel:paintcomponent()的功能,java,swing,jpanel,Java,Swing,Jpanel,您好,我是java编程新手,需要有人向我解释以下几行代码: public class drawpanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); ... } } 我不理解行public void paintComponent(Graphics g):如果在JPanel中预定义了该函数,为什么我必须
public class drawpanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
...
}
}
我不理解行public void paintComponent(Graphics g)
:如果在JPanel中预定义了该函数,为什么我必须这样声明它
这句话我一点也不懂。感谢您的帮助。是最初在抽象类JComponent中定义的方法。直接或间接扩展JComponent(如果公开)的组件可以选择覆盖paintComponent()。对
super.paintComponent(g)
的调用调用了paintComponent()
的超类实现(在您的例子中,它是JPanel的)。如果除了JPanel已经在做的事情之外,还想用图形g做其他事情,那么您需要覆盖paintComponent()
如果要更改绘制组件的方式,只需在类中定义paintComponent()
。在自定义实现中,需要调用super.paintComponent(g)代码>即paintComponent()
的基类版本,因为它做了一些必要的工作来准备绘制组件。基本结构:
extends
关键字意味着DrawPanel
继承自JPanel
。换句话说,DrawPanel
“是一个“JPanel
”。因此,它可以覆盖其方法(未标记为final
)的方法。出于几个原因,您可能希望这样做。例如,您可能希望访问面板的Graphics
类,可以使用该类在面板上绘制圆、条形图或文本字符串
如果您不重写任何方法,那么当您扩展JPanel
时,您会得到如下结果:
public class DrawPanel extends JPanel {
//TODO not much
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) { // <-- HERE!
//TODO draw stuff
}
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) {
g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
}
}
public class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g); // <-- HERE!
g.drawOval(50, 50, 50, 50);
}
}
但是,这不是很有用……除非您不喜欢名称JPanel
,并想将其称为AwesomePanel
(注意:不要这样做)。如果这就是您所拥有的,那么最好只创建JPanel
的实例,如下所示:JPanel drawPanel=newjpanel()代码>
油漆组件:
扩展JPanel
的目的是覆盖paintComponent
方法。JPanel
在覆盖paintComponent
之前是不可见的(注意:不可见使其成为按钮和其他组件的有用容器)。您是对的,paintComponent
方法是预定义的(如果您想知道的话,可以在JComponent
类中),但是该方法所做的只是将JPanel
设为空。如果要在面板上绘制某个对象,则需要覆盖它,如下所示:
public class DrawPanel extends JPanel {
//TODO not much
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) { // <-- HERE!
//TODO draw stuff
}
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) {
g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
}
}
public class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g); // <-- HERE!
g.drawOval(50, 50, 50, 50);
}
}
super.paintComponent:
有用的比喻(我刚刚编的):JPanel是画布,图形是你的画笔,超级。paintComponent(g)
是你的橡皮擦。(另外,JFrame
是您的画架。)
因此super.paintComponent(g)
从JPanel
(JComponent
类)的超类调用paintComponent
方法来擦除面板上当前绘制的内容这对动画很有用。
例如,考虑在面板上画一个模拟时钟。你需要每秒钟刷新一次,因此每秒钟你都必须擦除上一个时钟并重新绘制时钟,调整秒针。如果在重新绘制时钟之前不调用super.paintComponent(g)
,它将在旧时钟的基础上继续绘制新时钟,在60秒内,您将得到的只是一个或多或少的填充圆
只需记住一件事:始终在paintComponent
方法中首先调用super.paintComponent(g)
,如下所示:
public class DrawPanel extends JPanel {
//TODO not much
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) { // <-- HERE!
//TODO draw stuff
}
}
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) {
g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
}
}
public class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g); // <-- HERE!
g.drawOval(50, 50, 50, 50);
}
}
请阅读Java基础教程,如果您不知道这实际上意味着什么,就不应该重写方法。@om nom nom注意:答案很广泛,但有一个重要的缺陷。@kleopatra感谢您的更正paintComponent是由paint()方法调用的更新调用的。但是paintComponent()是什么呢事实上,你是怎么做的???你能给我一些教程的链接吗?这样我就可以知道如何使用它了。@jose你的paintComponent()除了调用基类的paintComponent()
之外,什么都没有做,或者至少什么都没有显示。调用super.paintComponent(g)
后,您可以执行其他操作;例如g.drawString(“helloworld!”,10,10)
mmm soo如果我不调用超类paintcomponent(),那么我就不能对图形进行更改,比如画一条线或任何形状??你知道从一开始就可以帮助我使用java图形的任何链接或书籍吗???超类的paintcomponent()会绘制面板,在大多数情况下,你可能不想跳过调用它。在调用super之后,您应该添加逻辑来绘制所需的任何内容。paintComponent(g)
-1 a)不可见是错误的b)子类必须保证符合其约定的不透明度:如果不透明(默认),他们必须用完全不透明的颜色填充整个内容区域,如果为假,他们可以自由地不填充整个区域。super.paintComponent是遵守约定的最简单方法(或者,您可以手动填充它,具体取决于不透明度设置)。无条件地只填充任意部分的覆盖(如标题为paintComponent的段落中所述)无效,这是对黑键的某种解释!这让我明白了很多