質問

I've recently started doing some tutorials in simple game making stuff.

so far it's been pretty basic stuff I can wrap my head around or already understood. However I've just done a tutorial on double buffering - http://youtu.be/4T3WJEH7zrc

Anyway, the piece of code i'm having trouble understanding is this:

public void paint(Graphics g) {
    dbImage = createImage(getWidth(), getHeight());     
    dbg = dbImage.getGraphics();                        
    paintComponent(dbg);                                
    g.drawImage(dbImage, 0, 0, this);                   
}

public void paintComponent (Graphics g) {           
    g.fillOval(x, y, 15, 15);                       
    repaint();                                      
}

So you create an image of the window, and then a graphic of that image (not too sure what the difference is there and couldn't find a simple enough definition to be satisfied with). you then pass the image into the 2nd method which creates an oval and then the window is updated via repaint (i'm pretty sure). Then finally, back in paint, the image is drawn.

So if someone could explain the flow of info to me and the difference between a graphic vs an image and the repaint command I'd be super thankful - cheers!

役に立ちましたか?

解決 2

This is a basic example of what's known as double buffering. Instead of painting directly to the device (via the Graphics context), you first render everything to a buffer (the dbImage in this case) and paint everything you need to it.

Once you are done, you render the resulting image to Graphics context of the device, in a single paint step. This reduces flickering when making lots of changes over a small period of time.

dbImage = createImage(getWidth(), getHeight());  

"Creates an off-screen drawable image to be used for double buffering", see Component#createImage for more details.

dbg = dbImage.getGraphics();   

Get's the images Graphics context. This is a unified API for painting, which makes it easy to draw to multiple different sources, such as the screen, printing or, in this, images

paintComponent(dbg);   

Off loads the painting to another method, which, as you say, draws a oval

g.drawImage(dbImage, 0, 0, this); 

Renders the result to the screen

The example is a little poor.

You should avoid calling repaint or any method that might cause repaint be to called from in any paint method as this will cause paint to be called again, which can quickly spiral out of control.

Also, you should dispose of any Graphics context that you create.

I would consider something like...

Image dbImage = createImage(getWidth(), getHeight());     
dbg = dbImage.getGraphics();                        
paintComponent(dbg);                                
dbg.dispose()
g.drawImage(dbImage, 0, 0, this);   

to be a slightly better example

Also I've just realised, nowhere else in my code are those methods called.... how are they just called for no reason?

See Painting in AWT and Swing for an explantion of how painting works

Updated based on additional comments

Generally, it's a bad idea to paint directly to top level containers, like JFrame or JPanel. Instead, you should use something like JPanel and override there paintComponent method.

Swing components are already double buffered, so you don't need to worry to much about it.

See Performing Custom Painting for more details

他のヒント

That code is terrible.

  1. Custom painting is done by overriding the paintComponent() method, not the paint() method and you should not be invoking paintComponent() directly.
  2. You would never invoke repaint() in a painting method because you will cause in infinite loop.

Here are a couple of better tutorials to read:

Performing Custom Painting - gives a simple example and explains basic painting in Swing
Painting in AWT and Swing - a more detailed explanation of how painting works

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top