Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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:paintcomponent()的功能_Java_Swing_Jpanel - Fatal编程技术网

Java 关注JPanel:paintcomponent()的功能

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中预定义了该函数,为什么我必须

您好,我是java编程新手,需要有人向我解释以下几行代码:

 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的段落中所述)无效,这是对黑键的某种解释!这让我明白了很多