What does super.paintComponent(g) do?
- What does it do?
It prints the component as if you hadn't overridden the paintComponent
method. If you have a background color set for instance, this is typically painted by the class you're extending.
- When do we need to use it?
You use it if you don't paint on the entire component. The parts that you don't paint will "shine through" which means that you should let the super class paint those parts. As with the example of the background color for instance: If you just paint a circle in the middle of the component, super.paintComponent
will make sure the background color is painted around the circle.
If you do paint the entire area of your component, then you will paint on top of whatever super.paintComponent paints and thus there's no point in calling super.paintComponent.
- What advantage does it gives us by writing it in paintComponent()?
That's the only logical place to put it. paintComponent
is called when the component should be painted, and, as mentioned above, if you don't paint the entire component yourself, you need super.paintComponent
to paint on the parts that shine through.
The documentation of paintComponent
says it pretty well:
[...] if you do not invoker super's implementation you must honor the opaque property, that is if this component is opaque, you must completely fill in the background in a non-opaque color. If you do not honor the opaque property you will likely see visual artifacts.
Java swing - super.paintcomponent(g) - repaint()
paintComponent
delegates to ComponentUI#update
, which sets the Graphics
context's color to the components background color and fills 0, 0, c.getWidth(), c.getHeight()
(where c
is a reference to the component been painted).
Basically, what this means is, even if you use repaint
or repaint(x, y, width, height)
, the background is begin completely updated.
The difference is, the Graphics
clip changes. When calling repaint
, the clip will be the size of the component, when using repaint(x, y, width, height)
, the clip shape will be the same as those values you passed it.
You may want to take a look at Painting in AWT and Swing for more details.
Remember, painting in Swing is under the control of the RepaintManager
, it will decide what and when something should be painted. When it decides that an update needs to take place, it will place a "paint" event onto the Event Queue, which will be processed, at some time in the future by the Event Dispatching Thread. This means, that under most circumstances, painting is not immediate...
use super.paintComponent(g) or getGraphics() in java
is it good practice to do this
No, this is actually incredibly horrible and error prone. This assumes that this is the Component#getGraphics
method. The problem is Swing uses a passive rendering algorithm, that is, Swing decides when and what should be repainted and does this for optimisation reasons.
This means updates are not regular, which really helps when doing animation, and can happen at any time for any number reasons, many of which you simply don't and can't control.
For these reasons, painting should be done within one of the paint methods, preferably, paintComponent
of a JComponent
based class. This way, when Swing decides to do a repaint, one, you know about it and can update the output accordingly, and two, it won't clear what you have previously painted to it using getGraphics
which could cause flickering...
You are also running into potential threading issues, as you thread is trying to paint to the Graphics
context, so might the Event Dispatching Thread and that isn't going to end pretty...All painting should be done from within the context of the EDT (for component based painting)
You could try using a BufferedStrategy
, which would give you direct control over the painting process, but this limits you to the AWT library. Don't know if this is good or bad in your case.
one other thing, how graphic.dispose() works correctly? , because
trying to remove this line of code, nothing happens.
dispose
basically releases any native resources that the Graphics
context might be holding. General rule of thumb, if you didn't create, you don't dispose of it.
So if you use Graphics#create
or BufferedImage#createGraphics
to obtain a Graphics
context, then you should call dispose
when your done with it.
On some systems calling dispose
on the Grpahics
context used to perform painting of components (such as that passed to paintComponent
or obtained from getGraphcis
) can prevent further content from been painted.
Equally, not disposing of Graphics
contexts that you have created can lead to memory leaks as they won't get garbage collected...
effects of not calling super.paintComponent in custom JPanel
call setOpaque(false) on the custom panel or draw with the Graphics object the entire component content
The problem with the code is that it is not honoring the opaque property http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics).
Calling super.paintcomponent(g) in class doesn't work
public class DrawPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.drawLine(0, 0,width,height);
g.drawLine(0, height, width, 0);
}
}
You should extend JPanel
super
refers to the immediate parents property. So in your case you can't call super because DrawPanel doesn't have a parent. You can solve that by adding extends JPanel
, which will also solve your .add()
problem in your main
method. .add() expects a Component
Related Topics
Execute Jar File with Multiple Classpath Libraries from Command Prompt
Java Implementation of JSON to Xml Conversion
Javafx: "Toolkit" Not Initialized When Trying to Play an Mp3 File Through Mediaplayer Class
How to Get Http Response Code for a Url in Java
Extracting Pairs of Words Using String.Split()
Spring 3 MVC: One-To-Many Within a Dynamic Form (Add/Remove on Create/Update)
Java: Exceptions as Control Flow
Sorting 2D Array of Strings in Java
Merging Two JSON Documents Using Jackson
Count Occurrences of Words in Arraylist
Can a Private Method in Super Class Be Overridden in the Sub-Class
Why Are Exceptions Not Checked in .Net
How to Use Urlclassloader to Load a *.Class File
What Is the Jvm Thread Scheduling Algorithm