Java 创建JFrame时是否调用paint()方法?

Java 创建JFrame时是否调用paint()方法?,java,swing,Java,Swing,我对java中的GUI非常陌生,但我使用的教程我了解所有内容,直到我说到这一点: 当我运行这段代码时,我得到一个椭圆形的框架(就像我想要的那样),但是什么时候调用paint方法呢 import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JFrame; import javax.swing.JPanel; public class Game e

我对java中的GUI非常陌生,但我使用的教程我了解所有内容,直到我说到这一点: 当我运行这段代码时,我得到一个椭圆形的框架(就像我想要的那样),但是什么时候调用paint方法呢

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Game extends JPanel {

    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;

        g2d.drawOval(0, 0, 30, 30);
        g2d.fillOval(0, 0, 30, 30);
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Single Player");
        frame.setSize(300,300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Game());
    }
}

Java在构造函数之后自动调用
paintComponent()
方法。 您可以在另一个函数/操作中手动调用
repaint()
方法,具体取决于您想做什么(如果您想在之后绘制一些东西)。
尝试总是调用
super.paintComponent(g)
在您的paint()方法中。

它也在
setVisible(true)
方法中调用,如图所示

让我更清楚一点。我必须承认我低估了调用
paint(Graphics g)
的次数。我知道它经常被
repaint()
调用,通常这种方法只有在
setVisible(true)
之后才有意义。这是一个粗略的估计,而且
repaint()
甚至没有直接调用
paint(Graphics g)


话虽如此,您始终可以在IDE中查找方法的调用层次结构(在Eclipse中这当然是可能的,我还没有在其他方法上尝试过)。为此,您只需调用该方法或在超类中覆盖它,例如,行
frame.paint(frame.getGraphics())可以(您想知道在哪里调用它的任何方法),您可以从弹出菜单中选择open call hierarchy来查看每个直接调用,并递归查看调用这些方法的方法在哪里被调用等等。

当swing必须绘制组件时调用它。您可以在eclipse调试模式下使用断点来了解代码流的工作方式。您可以在我的图像中看到调试点的使用(左侧的蓝点)。在代码的这一部分中,您可以在
setVisible()
方法中找到它,方法是在它旁边放置一个断点。断点在GUI编程期间是必不可少的

例如:

参考:

根据API文档:由Swing调用以绘制组件。应用程序不应直接调用paint,而应使用repaint方法来安排组件重新绘制

此方法实际上将绘制工作委托给三种受保护的方法:paintComponent、paintBorder和paintChildren。它们按列出的顺序调用,以确保子级显示在组件本身的顶部。一般来说,组件及其子组件不应在分配给边界的插图区域中绘制。子类可以像往常一样重写此方法。只想专门化UI(look and feel)委托的绘制方法的子类应该只覆盖paintComponent。

paint()
方法是在将
Game
类(扩展了
JPanel
)添加到
JFrame
时调用的。因为您正在游戏类中扩展JPanel。所以
Game
类扩展了
JPanel
,这个
JPanel
有一个
paint()
方法

g2d.drawOval(0, 0, 30, 30);
g2d.fillOval(0, 0, 30, 30);
因此,您的
paint()
方法在该语句中被调用

frame.add(new Game());
当您想在窗口中自己绘制一些东西时,会调用
paint()
。调用该
paint()
方法时,窗口将绘制在
paint()
方法中定义的项。因此,您在
paint()
方法中的代码在窗口中显示了两个项目,因为您正试图在
paint()
方法中绘制这两个项目

g2d.drawOval(0, 0, 30, 30);
g2d.fillOval(0, 0, 30, 30);

因此,您的
paint()
方法在位置x=0和y=0处绘制一个高度为30、宽度为30的椭圆,然后您的
paint()
方法在位置x=0和y=0处绘制一个高度为30、宽度为30的填充椭圆。因此,您只能在窗口中看到已填充的椭圆(
fillOval(0,0,30,30);
),该椭圆与上一个椭圆重叠(
drawOval(0,0,30,30);
)。

每当系统告知其状态已更改且需要重新绘制时,都会调用绘制方法。这是由您在代码中通过调用方法
repaint()
完成的,但教程使用的是
——如果教程建议覆盖paint(),则取消教程。自定义绘制应该通过重写
paintComponent(…)
方法来完成。阅读上Swing教程中的部分以了解更多信息和工作示例。1-,不应为paint()方法调用super.paintComponent()。进行自定义绘制的正确方法是重写
paintComponent()
方法,然后应调用
super.paintComponent()
作为第一条语句。