Java 什么叫做paintComponent()?

Java 什么叫做paintComponent()?,java,swing,java-2d,Java,Swing,Java 2d,我正在尝试从精灵表中绘制精灵 我有以下课程 public class GTComponent extends JComponent { Graphics2D g2; @Override public void paintComponent(Graphics g){ g2 = (Graphics2D)g; } public void drawSpriteFrame(Image source, int x, int y, int fram

我正在尝试从精灵表中绘制精灵

我有以下课程

public class GTComponent extends JComponent {

    Graphics2D g2;

    @Override
    public void paintComponent(Graphics g){
        g2 = (Graphics2D)g;
    }

    public void drawSpriteFrame(Image source, int x, int y, int frame) {
        int frameX = (frame % 12) * 32;
        int frameY = (frame / 12) * 32;
        g2.drawImage(source, x, y, x + 32, y + 32,
                frameX, frameY, frameX + 32, frameY + 32, this);
    }
}
在主类中作为对象创建的

    JFrame f = new JFrame();
    GTComponent img = new GTComponent();

    f.add(img);

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize((int)(i.length * 8.1), (int)(i[0].length * 8.5));
    f.setVisible(true);
    f.setLocationRelativeTo(null);

    BufferedImage test = null;
    try {
        test = ImageIO.read(new File( /*Image File path*/));
    }
    catch (IOException e) {
        System.out.println("error");
        System.exit(0);
    }

    img.drawSpriteFrame(test, (u * 32 + 1), (z * 32 + 1), c);
我面临的问题是抛出以下错误

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
在做了几次调试之后,在paintComponent和drawSpriteFrame上设置断点,我发现drawSpriteFrame方法在paintComponent方法之前被调用,这意味着g2=null会导致抛出该错误


这里的问题是什么触发了paintComponent方法,它允许我初始化g2变量?

您似乎对Swing中的绘图工作方式有着广泛的误解

如果需要,不调用任何渲染方法。在Swing需要时执行渲染。Swing调用paintComponent时,将在该组件中执行所有渲染。传递给paintComponent的图形应仅在您仍然使用paintComponent方法时才视为有效。方法退出后,它会发生什么变化

您可能希望参考有关Swing自定义绘制的教程,例如代码。

paintComponent是。如果希望自定义组件作为普通Swing绘制过程的一部分进行绘制,则应重写paintComponent以调用drawSpriteFrame方法,而不是直接调用drawSpriteFrame

如果希望自己控制绘图操作,则需要使用活动渲染-请注意,此处描述的技术也适用于窗口应用程序。基本上,您需要向窗口请求一个图形实例,而不是等待一个实例被传递到paintComponent,然后绘制到该实例

使用双缓冲的一个基本示例:

// Initial setup
Frame mainFrame = new Frame();
mainFrame.setVisible(true); // you'll also want to set size, location, etc.
mainFrame.createBufferStrategy(2);
BufferStrategy bufferStrategy = mainFrame.getBufferStrategy();

//.... 

// Inside your draw loop (call once for each frame)
Graphics2D g2 = (Graphics2D) bufferStrategy.getDrawGraphics();
g2.drawImage(...) // etc.
g2.dispose();
bufferStrategy.show();

为什么您仍然使用旧的AWT组件,而Swing提供了更好的渲染并自动启用双缓冲?因为如果您正在编写类似于游戏的东西,并且您正在执行所有自己的渲染,并且您需要对多缓冲区策略进行细粒度控制,那么您不一定需要Swing为您做的任何事情,事实上,Swing内置的双缓冲将成为阻碍。