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