Content of JDesktopPane dissappears when resized - Java Swing - java

I have been working on Java Swing for a while. I paint something(draw some basic shapes like circle,rectangle etc) on a JDesktopPane and once I resize the frame window that contains jDesktopPane or drag some other window over this frame, then the drawn shapes disappear. I use an object of the BufferedImage class so as to save the image. So Is there any way of preventing the shapes getting disappeared or repaint it when they disappear?

You need to make sure you are saving what you paint and repainting it each time in the paintComponent() method. This method is called automatically whenever a repaint is needed (for example: because of a resize).

I can only provide a guess since you've decided not to post the necessary code, but my suggestions are:
Don't get your Graphics object by calling getGraphics on a component. Instead,
Be sure to do your drawing in a class that subclasses a JComponent or one of its children (such as a JPanel).
draw your BufferedImage in the JComponent's paintComponent method immediately after calling super.paintComponent() in the same method. Use the Graphics object that is provided by the JVM and passed into the method's parameter.
To be sure that your paintComponent method's signature is correct, place an #Override annotation immediately before it. Otherwise if it is not correct, the JVM will probably not call it when you expect it to.
But also, please when asking a question here, try to give us enough information so we don't have to guess. Since your problem is graphics related, it would make sense to post your graphics-related code, right?

Related

Is it possible to paint without using a Frame of any sort in Java?

I am wondering whether I am able to use the paint method of Java's graphics class on something other than a JFrame--that is, no JFrames allowed. Is it possible?
Thanks in advance!
Graphics represents a graphic context, i.e. something you can draw on. In addition to GUI components like JFrame, JPanel etc. providing getGraphics() to access the visible gfx context, another common class that allows access to a gfx context is BufferedImage (or Image classes in general).
While painting on a visible GUI element immediately shows the results of the painting, using a BufferedImage allows you to perform the painting off screen into a buffer, and then painting the whole image at once (on a JFrame as you still need something visible) when you're ready to display the image. This is often used in animation and games when you need to avoid flickering for example.

Prevent JPanel from redrawing background on repaint() calls

Some animations (such as some gif files) only store in each frame the pixels that change from the previous frame. To draw these animations correctly, you have to paint the first frame, then paint the succeeding frames on top of them without erasing the previous frames. JPanels, however, always redraw the background when you call repaint(), erasing the previous frames. Is there a way to prevent a JPanel from redrawing the background? I've been told that calling super.paintComponent(g) in the JPanels paintComponent(Graphics g) method is what redraws the background, but I tried commenting that out and it lead to some strange behaviour, so I'm assuming it does more than just repaint the background.
I'd recommend to build your code upon the already existent code provided by the API instead of messing with it. Just store the image as BufferedImage. This allows you to display it using an ImageIcon, so it's an additional simplification. This allows you to update single pixels without any hassles with the API. If you absolutely insist on excluding the JPanel from the repaint-routine, this question might help.
In general:
Follow the conventional use of the API. If you want to permanently store data of an image, us a BufferedImage. JComponents are supposed to be entirely overridden every time the frame is updated.
Depending on your exact requirement there are two common approaches:
Draw on a BufferedImage and then display the BufferedImage
Keep an ArrayList of Objects you want to paint and paint all the Objects in the list every time paintComponent() is invoked.
Check out Custom Painting Approaches for more information and working examples of each approach.

Why does JCompnent.getBounds() always return 0 values?

When I try to get the bounds of a JPanel it always returns (
I use this.getBounds() in the constructor of the JPanel class):
java.awt.Rectangle[x=0,y=0,width=0,height=0]
At what point in the rendering of a Swing component does this actually get set? Is there an component event that happens after sizing of the bounds is made?
In the constructor of a GUI, the components have not yet been rendered, and so their bounds will be [0, 0]. The components only get rendered after calling pack() or setVisible(true) on the top level window such as a containing JFrame. But your question begs the question of why do you need this information here? What will you do plan to do with this data? There are other locations where the information can be obtained and can be useful, such as a JComponent's paintComponent method or in a ComponentListener.
Okay, thanks for the response, but I figured it out. Basically I need to override the paint() method from JComponent. At this point the rectangle bounds is properly produced. It really wasn't that complicated at all.
UPDATE:
Based on http://www.oracle.com/technetwork/java/painting-140037.html, it recommends using paintComponent() over paint() even though the API does allow it. This deals specifically with the component itself rather than all the related elements like borders and such.

Java - Repaint specific components

I'm learning Java as part of my degree but its very brief but what ever I do I like to make sure I atleast have some understanding.
Until now anything that I want displayed on the screen is put into the paintcomponent method of the JPanel.
However, I have drawn out some parts of my layout which never change, and only a certain thing in the middle rotates.
I have a timer which calls repaint().
If I correct in thinking that everything including the components that never change are being removed and then redrawn and the whole paintcomponent method is being run every time.
To me I feel like I should (or there must be) a way where the static stuff is moved out / is only drawn once, and only the parts that I specifically want to be redrawing should stay in the paintcomponent method?
Is this correct or am I not fully understanding something?
I am assuming that you are not adding GUI components in the paintComponent method, right?
Components are not "removed" during a repaint
Better to put the stable part of any image into a single background BufferedImage and draw the BufferedImage in the paintComponent method. This can make for more efficient painting.
Consider calling an overload of repaint(...) that sets a bounding rectangle for the region to be painted.

Any alternative to calling getGraphics() which is returning null

Frequently when I call getGraphics() it returns null, even if I set the xxx.getGraphics(); xxx to be visible (as a Google search shows...)
But this doesn't work, and this frustrates me as it is easy and simple to do in C-Sharp.
Does anyone know of a better way of doing this instead of using getGraphics()??
You usually don't want to use getGraphics on a Java Swing component since this will be null if the component has not been rendered yet, and even if the component has been rendered and the Graphics object returned is not null, it will usually be a short-lived object and will not work properly if the component gets repainted (a process that is out of your control).
A better alternative is to draw in a JComponent's paintComponent method and using the Graphics object passed into this method as its parameter. If you need to draw something that is to be a background image, also look into drawing on a BufferedImage. When you do that, here you will call getGraphics() on the image (or createGraphics() if you need a Graphics2D object), and here the object returned will be stable. You'll still need to display this image somehow, either as an ImageIcon displayed by a JLabel or as an Image displayed in a JComponent's paintComponent method, by calling Graphics#drawImage(....) on the paintComponent's Graphics parameter.
Don't use getGraphics(). Any painting you do will be temporary and will be lost the next time Swing determines a component needs to be repainted.
Instead override the paintComponent() method of a JComponent or JPanel to do your custom painting. See Custom Painting for more details and examples.

Categories

Resources