Java:图像,图形和面板

时间:2018-08-26 08:20:32

标签: java swing

我正在尝试用Java制作动画,但是难以理解DoubleBufferImage和DoubleBufferGraphics。我了解update(),render()和paint()序列。但是,在每种方法中,我无法理解它是如何绘制的。这是代码。

  1. gameUpdate() ///因为我首先需要了解背景,所以我将跳过更新部分。

  2. gameRender()

    private void gameRender() {
        if (DoubleBufferImage == null) {
            System.out.println("The Image is null: Error occurence");
            DoubleBufferImage = createImage(P_WIDTH - 15, P_HEIGHT - 15);
        }
    
        DoubleBufferGraphic = DoubleBufferImage.getGraphics();
    
        DoubleBufferGraphic.setColor(Color.LIGHT_GRAY);
        DoubleBufferGraphic.fillRect(0, 0, P_WIDTH, P_HEIGHT);
    
        DoubleBufferGraphic.setColor(Color.BLUE);
        DoubleBufferGraphic.setFont(font);
        DoubleBufferGraphic.drawString("Average FPS/UPS: " + 
                df.format(averageFPS) + df.format(averageUPS), 10, 10);
    }
    
  3. paint()

    public void paintScreen() {
        Graphics g;     
        try {           
            g = this.getGraphics();
            if ((g != null) && (DoubleBufferImage != null)) {               
                g.drawImage(DoubleBufferImage, 0, 0, null);         
            }           
            Toolkit.getDefaultToolkit().sync();     
        } catch (Exception e) {         
            System.out.println("Graphics context error: " + e);     
        }   
    }
    

还有从Jpanel覆盖的paintComponent方法。

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (DoubleBufferImage != null) {
        g.drawImage(DoubleBufferImage, 0, 0, null);
    }
}

这是我的问题。运行就像更新->渲染->和绘画 但是,从渲染中可以看到,他们使用图形进行绘制。但这都是在DoubleBufferImage中绘制的吗?图像实例是否类似于面板实例?我的意思是,它是否可以添加到框架中? 因为这是Double Buffering系统,所以我想知道哪些方法是直接绘制的,哪个是事先绘制的方法。 最终,在运行中,没有代码要添加到面板中,这是我们制作的图像或图形。我只想知道BufferedImage被绘制的时间。 请帮忙!我无法上传整个代码,所以我不确定你们是否能理解:(

1 个答案:

答案 0 :(得分:1)

好的,所以您似乎正在对一些错误信息和误解进行打击。也许您应该先看看类似paintComponent() vs paint() and JPanel vs Canvas in a paintbrush-type GUI

的东西

在AWT / Swing中,至少有两种执行自定义绘画的方法,每种方法各有利弊。

您可以使用paintComponent,它是Swing使用的绘画系统的“钩子”。 Swing利用“被动”渲染系统。这意味着您无法控制何时绘制某些内容,绘制系统做出这些决定,然后(间接)调用组件的paintComponent,以便您可以执行更新。

另一种机制(BufferStrategy)使用“活动”渲染系统,该系统可以完全控制何时进行绘画。

通常,您不能混合使用它们。 Swing拥有自己的绘画系统,因此无法与BufferStrategy配合使用,因此,这意味着如果您希望将Swing组件用作输出的一部分,则不能。

但这不会回答您的问题,或者不能直接回答

让我们尝试将其分解

gameRender

private void gameRender() {
    if (DoubleBufferImage == null) {
        System.out.println("The Image is null: Error occurence");
        DoubleBufferImage = createImage(P_WIDTH - 15, P_HEIGHT - 15);
    }

    DoubleBufferGraphic = DoubleBufferImage.getGraphics();

    DoubleBufferGraphic.setColor(Color.LIGHT_GRAY);
    DoubleBufferGraphic.fillRect(0, 0, P_WIDTH, P_HEIGHT);

    DoubleBufferGraphic.setColor(Color.BLUE);
    DoubleBufferGraphic.setFont(font);
    DoubleBufferGraphic.drawString("Average FPS/UPS: " + 
            df.format(averageFPS) + df.format(averageUPS), 10, 10);
}

此时,DoubleBufferImage似乎是BufferedImage,因此在调用gameRender时,它将检查是否存在缓冲区并根据需要创建它。然后,它引用DoubleBufferImage的{​​{1}}上下文,并准备对其进行渲染,从而清除以前为其绘制的内容。

Graphics

的简要概述

Graphics是位于基础渲染管道上方的抽象层,取决于系统,通常使用OpenGL或DirectX来实现。它提供了一个公共层,可以以与系统无关的方式在其上执行图形操作

Graphics

paintScreen

这让我感到担忧,因为我没有上下文,但是public void paintScreen() { Graphics g; try { g = this.getGraphics(); if ((g != null) && (DoubleBufferImage != null)) { g.drawImage(DoubleBufferImage, 0, 0, null); } Toolkit.getDefaultToolkit().sync(); } catch (Exception e) { System.out.println("Graphics context error: " + e); } } 似乎正在引用组件的this.getGraphics()上下文,并向其绘制Graphics

这是危险且不明智的。 DoubleBufferImage返回组件上次绘制时的快照,可以在再次绘制组件时随时对其进行绘制。

您应该尽早摆脱这种方法。

getGraphics

paintComponent

如上所述,public void paintComponent(Graphics g) { super.paintComponent(g); if (DoubleBufferImage != null) { g.drawImage(DoubleBufferImage, 0, 0, null); } } 是挂接到Swing的绘画系统中的首选方法。尽管它实际上应该显示为paintComponent

,但它所做的只是绘制DoubleBufferImage

那么,这是怎么做的?

基本上,这是在Swing中执行双重缓冲的不当尝试,默认情况下已经双重缓冲。

  

但是,从渲染中可以看到,他们使用图形进行绘制。但这都是在DoubleBufferImage中绘制的吗?图像实例是否类似于面板实例?

不。组件是一个对象,它具有许多属性。它的工作之一就是绘制状态,这是通过各种绘制方法完成的,传递给g.drawImage(DoubleBufferImage, 0, 0, this);上下文,该上下文附加到本机对等项,并最终呈现到屏幕(或打印机)。 / p>

Graphics就是图像。 BufferedImage上下文只是一种简单的绘制方法。然后可以将其保存到文件中,或者像在此处一样,(通过Graphics绘制到组件上下文中。)

如上所述,Graphics只是一个抽象层,它使您可以对许多不同的目标,屏幕,打印机,图像等进行绘画操作。

  

我的意思是,它是否可以添加到框架中?

不。它不是基于组件的类

  

因为这是Double Buffering系统,所以我想知道哪种方法是直接绘制的,哪种方法是事先绘制的。

Graphics和(不建议使用的)paintComponent将图像直接绘制到组件上,该组件最终将通过绘制子系统呈现到屏幕上。

进一步阅读...