This might be a very noob question. I'm just starting to learn Java
I don't understand the operation of paintComponent method. I know if I want to draw something, I must override the paintComponent method.
public void paintComponent(Graphics g)
{
...
}
But when is it called? I never see anything like "object.paintComponent(g)" but still it is drawn when the program is running.
And what is the Graphics parameter? Where is it from? Parameter must be supplied when the method is called. But as I said before, it seems like this method is never be explicitly called. So who provides this parameter? And why do we have to cast it to Graphics2D?
public void paintComponent(Graphics g)
{
...
Graphics2D g2= (Graphics2D) g;
...
}
The (very) short answer to your question is that
paintComponent
is called "when it needs to be." Sometimes it's easier to think of the Java Swing GUI system as a "black-box," where much of the internals are handled without too much visibility.There are a number of factors that determine when a component needs to be re-painted, ranging from moving, re-sizing, changing focus, being hidden by other frames, and so on and so forth. Many of these events are detected auto-magically, and
paintComponent
is called internally when it is determined that that operation is necessary.I've worked with Swing for many years, and I don't think I've ever called
paintComponent
directly, or even seen it called directly from something else. The closest I've come is using therepaint()
methods to programmatically trigger a repaint of certain components (which I assume calls the correctpaintComponent
methods downstream.In my experience,
paintComponent
is rarely directly overridden. I admit that there are custom rendering tasks that require such granularity, but Java Swing does offer a (fairly) robust set of JComponents and Layouts that can be used to do much of the heavy lifting without having to directly overridepaintComponent
. I guess my point here is to make sure that you can't do something with native JComponents and Layouts before you go off trying to roll your own custom-rendered components.The internals of the GUI system call that method, and they pass in the
Graphics
parameter as a graphics context onto which you can draw.Calling
object.paintComponent(g)
is an error.Instead this method is called automatically when the panel is created. The
paintComponent()
method can also be called explicitly by therepaint()
method defined inComponent
class.The effect of calling
repaint()
is that Swing automatically clears the graphic on the panel and executes thepaintComponent
method to redraw the graphics on this panel.Two things you can do here:
Just for info, here is the stacktrace that I got from the example of code I posted at the end:
The Graphics parameter comes from here:
The snippet involved is the following:
If you take a look at it, you will see that it retrieve the graphics from the JComponent itself (indirectly with
javax.swing.JComponent.safelyGetGraphics(Component, Component)
) which itself takes it eventually from its first "Heavyweight parent" (clipped to the component bounds) which it self takes it from its corresponding native resource.Regarding the fact that you have to cast the
Graphics
to aGraphics2D
, it just happens that when working with the Window Toolkit, theGraphics
actually extendsGraphics2D
, yet you could use otherGraphics
which do "not have to" extendsGraphics2D
(it does not happen very often but AWT/Swing allows you to do that).