Java中的Graphics类如何工作?

时间:2012-08-04 06:46:47

标签: java swing graphics paintcomponent

最近,我一直在尝试用图形做一些Java工作。现在Graphics类是抽象的,这意味着它本身不能被实例化,但它的子类可能能够被实例化。那么下面的代码中发生了什么。 (这确实成功创建了一条线)

import javax.swing.*;
import java.awt.*;

public class line extends JPanel {
    public void paintComponent(Graphics g) {
        g.drawLine(0, 0, 90, 90);
    }

    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.add(new line());
        jf.setSize(500, 500);
        jf.setVisible(true);
    }
}

好的,现在有一些事情对我没有意义。首先,当调用line时,它必须在line类中执行paintComponent方法。这是静态方法的属性(使用类名称调用)。但paintComponent方法没有静态修饰符。

由于这个程序有效,我们必须假设paintComponent被调用并且期望一个Graphics对象作为参数。虽然它没有参数被调用。为什么这不会产生错误?我运行了一些测试,传入一个字符串,然后没有任何东西进入一个期望一个Integer对象的方法。我在这两个程序上都有错误。

所以不知何故创建了一个名为g的图形对象,并使用了drawline方法。但是图形是抽象的。

好的,这是我的问题:

  1. 当paintComponent不是静态时,为什么在调用类行时会自动调用paintComponent?

  2. 为什么paintComponent在需要Graphics对象时会接受空参数?

  3. 然后如何制作Graphics对象,因为Graphics类是抽象的,无法实例化?

  4. 帮我Stack Overflow,你是我唯一的希望。

    编辑: 好的,我认为这个问题得到了很好的回答,谢谢!

3 个答案:

答案 0 :(得分:9)

  1. 当AWT决定是时候绘制窗口时调用paintComponent(在大多数情况下,因为操作系统向它发送一条消息告诉它这样做)。当它绘制JFrame时,它遍历其中的对象树。其中有你的line实例,因为你用jf.add(new Line())调用添加了它。在每个上面调用paintComponent方法。

  2. 它不接受空参数。

  3. 当AWT调用paintComponent时,它会传递一个继承自Graphics的具体类的实例。

  4. 签名paintComponent(Graphics g)并没有说参数应该完全是Graphics类型。但实际上它应该是Graphics类型或继承自Graphics的任何类。另一种看待它的方法是说任何继承自Graphics的类也是Graphics类型。

答案 1 :(得分:0)

在小程序内的屏幕上绘制线条,形状,字符和图像。 Java中的大多数图形操作都是Graphics class中定义的方法。您不必创建Graphics实例就可以在applet中绘制内容;在applet的paint()方法中,您将获得一个Graphics对象。通过绘制该对象,您可以绘制到applet上,结果将显示在屏幕上。 Graphics类是java.awt包的一部分,所以如果你的applet做任何绘画(通常会这样),请确保在Java文件的开头导入该类........... ...

答案 2 :(得分:0)

您必须知道的是,paintComponent()仅由AWT调用,而不是您第一次调用。但是您可以使用方法“ repaint()”,因为它在内部调用paintComponent()来更新图形。图形对象也是由Graphics的内部子类创建的。因此,在调用paintComponent()之前,AWT将创建扩展Graphics的类的对象(假设g)。之后,AWT通过传递“ g”对象来调用您定义的paintCompoent()。

这与actionPerformed()方法在侦听器上使用的方法相同。您只是定义它,但实际上不知道它在哪里被调用。实际上,这些是由JVM(Java虚拟机)执行的任务:

jbutton.addActionListener(new ActionListener(){
   public void actionPerformed(ActionEvent e){
      //Do sth on button click.
   }
});