When the Graphics instance is created - java

I know that when paint is happening an instance of the Graphics class should be created. That Graphics object (Actually Graphics2D object) is going through paint() method and all the details that should be printed or updated on the screen are stored in that object.
As I know of this process is handled by RepaintManager when user called repaint() method or when repaint is needed to the UI. So, a Graphics instance has to be created to store the information regarding the painting.
As this process is handled by RepaintManager, I thought that the Graphics instance is also initialized inside RepaintManager. But I found source code of RepaintManager recently. And couldn't find a place that a new Graphics instance is created.
So, is it really created inside RepaintMananger or anywhere else..?
Thanks..

It's created in Component.getGraphics() see the API for more information

Related

paintComponent() is being invoked 200 times

I am having an odd issue when using paintComponent() and repaint().
As you see below, I have a paintComponent() class as an inner class as the main JPanel of my GUI.
// add another panel to centerInner
tableBottom = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (!paintImages.isEmpty()) {
for (PaintImages temp : paintImages) {
g.drawImage(temp.getImage(), temp.getX(), temp.getY(), this);
}
}
if (!extraCards.isEmpty()) {
for (PaintImages temp1 : extraCards) {
g.drawImage(temp1.getImage(), temp1.getX(), temp1.getY(), this);
}
}
}
};
This is a black jack game with 4 players a dealer.
repaint() is called by 4 functions:
The constructor for the initial draw.
An update method that creates an ArrayList of objects to print for the initial deal.
An another update method that creates an ArrayList for each card drawn.
And the reset which clears all ArrayLists and repaints the new initial deal.
I won't go into the backend, but every one of those four methods only run the desired number of times. just once for every time its called.
My problem is that when paintComponent is invoked by repaint(), paintComponent() runs almost 200 times, not including the for loops that run around 10 times a piece on average per game.
My question is:
1) Is this common behavior for a paintComponent method? Does paintComponent call itself repeatedly over and over again until all painting necessary has been completed?
OR
2) Does this have to do with the JPanel tableBottom? at this point nothing is actually being added to the JPanel because it is top most JPanel. But maybe paintComponent is ran repeatedly for every JPanel, JFrame, ContentPane, Label, etc.,
OR
3) Did I do something wrong in my code below? Again through testing using increments and print statements I found the update methods are called the appropriate amount of times and doing their jobs correctly.
Thanks for any help.
being a inner class I call repaint like tableBottom.paintComponent()
Never invoke the paintComponent() method directly. To repaint the panel you do:
tableBottom.repaint();
The request will be passed to the RepaintManager which will then combine repaint() requests for all components and then paint the components as necessary. This will make painting more efficient.
g.drawImage(temp1.getImage(), temp1.getX(), temp1.getY(), this);
The "this" means that images can be repainted as they are being read. That is sometimes the painting method is invoked before the image I/O has completed. So in this case when the I/O is finished another paint request will be made so the image is painted completely. If you are reading the images at the start of you class and storing them in some data structure then you can probably just use "null" instead of "this".
Did I do something wrong in my code below?
The code provide looks reasonable, but we can't see the context of how/when you invoke the painting code. I already mentioned one problem.
Post a proper SSCCE that demonstrates the problem.

Calling drawing on JFrame from another class

I've got a class in which there is a method that draws rectangles on a JFrame. Furthermore I've got a few methods with different types of sorting. In those sorting methods I am calling the drawing method when a specified button is clicked. I would like my code to be cleaner, so I wanted to divide the class into one that is responsible for drawing things and the other one that does the sorting. I don't know how I can call the drawing method from outside the class. I wanted to use static, but I would have to make all the variables inside the method static. I also thought about making an inner class, but I will still have that one big class and it doesn't really help. What can I do?
You should only be drawing from within the paintComponents method of the container. So it doesn't make sense for some external code to initiate a call to draw stuff. If you want this external class to change what is drawn, it should pass a reference to an object implementing some understood interface that can be called by the paintComponents method.

Hijack `repaint()` call in Java Swing component

I'm writing an app which runs in a headless environment and needs to output to a BufferedImage instead of a screen. I have a Display class managing the BufferedImage. My app extends JPanel and in order to make it automatically repaint when a component updates, I've re-implemented repaint() as:
public void repaint(){
Graphics2D g = getDisplay().getGraphics();
paint(g);
getDisplay().repaint();
}
Whenever I start up my app, though, I get a NullPointerException when it tries to draw to the Display. This is supposedly some code in the JPanel constructor that tries to repaint. The problem is that getDisplay() returns null. However, the Display has already been instantiated and passed to the app at this point. I've verified this by having the Display print out its own properties on creation, before sending it to the app.
The exception is as follows; the topmost location refers to the line containing getDisplay():
Exception in thread "main" java.lang.NullPointerException
at com.mypapyri.clay.ui.App.repaint(App.java:28)
at javax.swing.JComponent.setFont(JComponent.java:2746)
at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:208)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:66)
at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:56)
at javax.swing.JComponent.setUI(JComponent.java:655)
at javax.swing.JPanel.setUI(JPanel.java:153)
at javax.swing.JPanel.updateUI(JPanel.java:126)
at javax.swing.JPanel.<init>(JPanel.java:86)
at javax.swing.JPanel.<init>(JPanel.java:109)
at javax.swing.JPanel.<init>(JPanel.java:117)
at com.mypapyri.clay.ui.App.<init>(App.java:18)
at ClayOS.<init>(ClayOS.java:22)
at ClayOS.main(ClayOS.java:84)
EDIT: I've researched this and could not find a satisfactory resolution.
The repaint() method and the GUI thread
Javadocs for Component
PaintManager and RepaintManager
nidu told it first, but since he doesn't answer I put it.
Probably you're calling super() in the constructor method, and the JPanel constructor is trying to repaint before the display has been set.

ImageObserver Class not found

So i have an image being drawn inside a void method in my main class, and every tutorial i have looked at has told me to just write 'this' in the last field of the drawImage() method.
Unfortunately, obviously since this is inside a void method, 'this' does not work.
How do I deal with this?
Is there a way to create a local ImageObserver variable?
I dont need to use it really.
Code snippets:
URL iurl = new URL("cyn.png");
Image bi = Toolkit.getDefaultToolkit().getImage(iurl);
graphics.drawImage(bi,d.width/2+10,110,128,128,iob);
i dont know what else i need to show
i imported the Image class and graphics class
How do I deal with this? Is there a way to create a local ImageObserver variable? I dont need to use it really.
If you don't need to use the image observer, you can safely pass null as argument. (It's basically only used when loading images asynchronously.)
From The Java™ Tutorials: Drawing an Image:
The observer parameter notifies the application of updates to an image that is loaded asynchronously. The observer parameter is not frequently used directly and is not needed for the BufferedImage class, so it usually is null.

Java Swing: repaint() vs invalidate [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Java Swing revalidate() vs repaint()
Hi all
I'm fighting with my program to make it refresh at the right time.
And not having a lot of success lol
I have 2 questions
Q1: which should I use when my interface has changed: repaint or invalidate?
Q2: when should they be called? I know it sounds stupid but I'm actually having problems because of SwingWorker and other threaded operations.
Q1: which should I use when my
interface has changed: repaint or
invalidate?
If the layout is not up to date because of resizing , font change etc then you should call invalidate. Invalidating a component, invalidates the component and all parents above it are marked as needing to be laid out. Prior to painting, in the validation step if no change is found then the paint step is left out.
If there is some part of component which is being updated (defined by the graphic's clip rectangle, called "damaged" region) then you should consider calling repaint. One of the reason a damaged regions may occur is from the overlapping of a part of your component because of some other component or application.
As per my experience the repaint() is more effective if you call it on the innermost enclosing component (i.e. using public void repaint(int x, int y, int width, int height) rather than using public void repaint()).
Q2: when should they be called?
Invalidate(): marks a component as not valid -- that means, it's layout is or may not be "up to date" anymore: i.e. the component is resized, a border is added, it's font changes, etc. you should never need to call invalidate() by hand, as swing does that for you on pretty much for every property change.
When more than one region within the control needs repainting, Invalidate will cause the entire window to be repainted in a single pass, avoiding flicker caused by redundant repaints. There is no performance penalty for calling Invalidate multiple times before the control is actually repainted.
Repaint() : If the component is a lightweight component, this method causes a call to this component's paint method as soon as possible. Otherwise, this method causes a call to this component's update method as soon as possible.
Also have look at Update method.
NOTE: Swing processes "repaint" requests in a slightly different way from the AWT, although the final result for the application programmer is essentially the same -- paint() is invoked.
Refer to the link below for an excellent link on how painting is done in AWT and Swing:
http://www.oracle.com/technetwork/java/painting-140037.html
Hope this will help.

Categories