difference between JFrame.repaint() and JPanel.repaint() - java

can please anyone explain the difference between JPanel.repaint() method and JFrame.repaint() method, i guess both calls the paintComponent() method in JPanel.
Please clarify, thanks

Calling repaint() on any Component will add a request to the repaint manager to paint that component. If conditions are correct, the manager will then arrange to have the Component's paint(...) method called. Since a Component's paint method will then call paintComponent(...), paintBorder(...) and paintChildren(...) this will have the component paint itself, its border and cascade painting recursively to all of its children, their children, their children's children, etc. Calling this on JFrame will cause this cascade to occur throughout the entire top-level window whereas calling it on a subcomponent will cause a repainting of that component and its children only.
Note that calling repaint() does not guarantee that the repaint manager will paint the component, especially if there are stacked requests. For more on the details, please read Painting in AWT and Swing.

1. When repaint() method is called then the Event handler thread notifies all the components , and then every component calls their paintComponent() method.
2. Calling JPanel.repaint() will have all the component within the JPanel to repaint(), and calling JFrame.repaint() will have all the component within the JFrame to repaint() .
3. Call JFrame.repaint() to repaint the JPanel too without the need of JPanel.repaint()....

In brief,
JPanel.repaint() will repaint itself and its children.
JFrame.repaint() will repaint itself and its children. But since JFrame is the base, this will repaint every component within.
Check "#Hovercraft Full Of Eels" answer for details.

Related

JComponent: how to do a repaint in the most correct way?

We have following methods:
java.awt.Component#repaint()
This is old method that repaints in AWT. It does not repaint immediately, it schedules repaint.
javax.swing.JComponent#repaint(long, int, int, int, int)
This is new swing method that repaints in Swing. It schedules repaint with the RepaintManager.
Both of them may be invoked from a user thread as well as from the event-dispatching-thread.
Which of them is the most correct way to repaint Swing component (JComponent)?
Which of them is the most correct way to repaint Swing component (JComponent)?
Both of them are the correct way.
Swing components always invoke repaint() when you change a property of the component by using setText(), setForeground(), setBackground() etc. This will make sure the entire component is repainted.
The repaint(...) method can be invoked if you need to optimize painting of the component. If you have a large component and only a small part of the component changes you can use this method. However, I would recommend you don't worry about this. Swing painting is double buffered and efficient so there is rarely a case when you need to optimize the painting code.

JPanel derived class in JFrame - painting duplicate

I've added my JPanel derived class to the JFrame. Now when I want to draw an oval (using fillOval in my JPanel's paintComponent method) I see two ovals being painted. The problem disappears when I invoke super.paintComponent or when I invoke setContentPane in the JFrame class with my JPanel as parameter. The question is, why does it happen? Of course when the upper left corner of both JPanel and JFrame are in the same place, it doesn't happen. But somehow the JPanel isn't opaque unless I invoke super.paintComponent. The main question is why does it paint BOTH on the default content pane AND my JPanel. Thanks for help.
" The main question is why does it paint BOTH on the default content pane AND my JPanel."
It just appears that way, but actually you are seeing both being drawn on the panel. Always call super.paintComponent in the paintComponent method (no if ands or buts) or you will see paint artifacts as the one you're experiencing. The paintComponent method can be called for any number of reasons, and each time it's called, is another opportunity for paint artifacts to appear. Calling super.paintComponent wipes those out. When you set the content pane to the panel, it appears the paintComponent method is not being called more than once, so you don't get those artifacts. But to reiterate, always call super.paintComponent. Setting the content pane has nothing to do with the problem or the solution.

Difference between paint() and repaint()

I am a novice Java programmer and I'm finding quite some difficulty in figuring out the actual difference between the functioning of the paint() and repaint() method.
Also in some of the programs that I studied I found paint() and repaint() interchangeable.
Can someone please explain the difference? Thank you
Assuming that you are referring to the void paint(Graphics g) method that is declared in the Component class:
This paint method is called automatically, whenever it is necessary to paint (parts of) the component. For example, when the window was obstructed by another window and then becomes visible again: The window manager will determine this, and call paint on the top level component (e.g. a Frame) and this call will make its way down to the actual "bottom" components (e.g. a Button). The Graphics object that is passed to this method is provided by the Window manager, and corresponds to the area on the screen where the component should be painted. (And this Graphics object is only valid during the paint method).
In contrast to that, repaint() just triggers a new painting process. It is telling the system: "Please call paint on this component as soon as possible". You can call this method manually. And you can call it freuqently: The calls to repaint are coalesced. That means that when you issue many calls to repaint in a short period of time, then these calls may be summarized and may eventually only trigger one call to paint.
The paint method should not be called directly as the javadoc states:
Invoked by Swing to draw components. Applications should not invoke
paint directly, but should instead use the repaint method to schedule
the component for redrawing.
The repaint method should be used instead if you want the component to be repainted (redrawn). The javadoc also refers to the following documentation: Painting in AWT and Swing
paint() get called automatically at runtime. If you want to call paint() manually(again) then repaint() is used.
The paint() method contains instructions for painting the specific component.
The repaint() method, which can't be overridden, is more specific: it controls the update() to paint() process. You should call this method if you want a component to repaint itself or to change its look (but not the size).

What triggers an implicit call to paint() for a component in AWT?

I was reading through this:
http://www.oracle.com/technetwork/java/painting-140037.html#triggers
And it mentions the following:
In a system-triggered painting operation, the system requests a
component to render its contents, usually for one of the following
reasons:
The component is first made visible on the screen.
The component is resized.
The component has damage that needs to be repaired. (For
example, something that previously obscured the component has moved,
and a previously obscured portion of the component has become
exposed).
The first point is fairly obvious. However, the second and third points leave something to be desired when determining if I need to call repaint(). Almost any example I see calls repaint() whenever a component's graphical properties change at all. However, there is some indication that if I change certain properties I shouldn't have to call repaint(). What might those properties be?
When you have a method that changes a property of the component that affects the way the component will be painted, then that method should invoke repaint(), not the application code. That is the repainting should be hidden from the programmer.
I don't understand what you mean by changing the clipping of the panel. Clipping is something that is done during the painting process. So if you have a property that affects the way you want the painting to be done, you invoke the method that changes that property, that method invokes repaint() and if the clipping area has changed, then your painting routine will use that information while doing the painting.

How to cancel a repaint of a JPanel?

I know that JPanel is, by default, automatically double-buffered. However, I have a particularly time-intensive painting operation in my panel, but the panel only needs to be repainted when the underlying data changes, which is rare. Therefore, I'd like to reuse the JPanel buffer instead of having it clear after every call to repaint().
I've manually implemented a "dirty" flag on my JPanel subclass, but I have no idea how to cancel a paint operation once it's been started. I can't avoid the call to repaint in the first place, since my panel is inside a JScrollPane, which is being repainted every time it's resized (which does happen frequently), which causes my custom panel to be repainted.
Is there any way to do this without manually buffering the panel? If not, what's the recommended method for implementing a manual buffer in conjunction with a JPanel?
I have a particularly time-intensive painting operation .. only needs to be repainted when the underlying data changes, which is rare..
Paint the data to a BufferedImage, display it in a JLabel. Call label.repaint() if it changes. E.G. as seen in this answer.
Bonus Showing an image in a label is a way to get a GUI with a preferred size, that does not need to extend anything. To get the perfect size for the frame or dialog that displays it, call pack().

Categories