Java setClip seems to redraw - java

I'm having some troubles with setClip in Java. I have a class that extends JPanel. Within that class I have overridden the paintComponent method. My paintComponent method looks something like this:
paintComponent {
//draw some lines here
Rectangle whole = g2.getClipBounds();//g2 is my Graphics2D object
Rectangle part = <some rectangle that is a part of the whole paintable area>;
g2.setClip(part);
//draw some more stuff here
g2.setClip(whole);
}
The problem that I'm seeing is that the area in the clipped region seems to be painted repeatedly. For example, if I tell it to paint, it paints just fine. But then, if I switch windows or somehow else cause it to paint the same thing again, the clipped region isn't cleared while the rest is. This results in the painting on the clipped region to appear bolder than the rest of the paintable area.
I imagine that I'm missing something in how setClip works.
Any suggestions would be much appreciated. Thanks in advance for any help.

Creating a new Graphics object from the old one did the trick for me, as adviced by Tom.

Related

JPanel repaint does not work

I am developing a graphic project in java using swing and awt libraries. I am looking for a method that allow me to draw very fast on my JPanel. I tried various methods: overriding paintComponent, calling repaint(x, y, width, heigth).. But in all cases i have to repaint ALL the screen! I have a background and a small image in front of it that changes every few time. i am looking for a method that allow me to paint on the screen only the small image, i don't need to repaint the background too, because it is always the same, and the small image is always at the same coords. for example in C++ i painted the background and then i only painted the small images in front of it using putimage (graphics.h), so that it was very very fast. Do someone have some tips?
I've had some experience with game programming and usually a JPanel is used as canvas. Now to paint on it you would write a simple loop which continuously buffers an image and later paints it to the screen. So on initialisation you create a Graphics or Graphics2D object which is passed to a buffer() method. After painting a BufferedImage with the Instance of Graphics, some paint() method paints the BufferedImage to the screen.
When only painting the background once, previously drawn images will still be visible. If all your images are the same size, you don't have to bother but I still recommend repainting your background as well.
Have a look at the book Killer Game Programming In Java for further information, it's a great reference.
Tips:
Paint static images to a BufferedImage and then draw that within the paintComponent using Graphics#drawImage(...)
You do know that the repaint(...) method is overloaded and that one overload can accept a Rectangle parameter, limiting the area of repainting.

Passive rendering method

I am building a simple game rendering method. I have a static images like map background that isn't really changing at all . I am just using like 30% of the whole screen for changing graphics. And I don't feel like it is necessary to render all that stuff over and over again if it isn't changing..
on internet I found something about passive rendering - You draw what you need and wait... until something updates .. after that you update it and again wait.
Looks like a great method for this situation . But now ...
I have a render method like that :
public class X extends Canvas{
//some method
this.createBufferStrategy(3);
//....
public void render(){
BufferStrategy buffer = this.getBufferStrategy();
Graphics g = buffer.getDrawGraphics();
//Draws black background...
g.setColor(Color.BLACK);
g.fillRect(....
for(... //cycles every object and calls their render methods...
}
This is unable to maintain draw and wait method...becouse the background is redrawn every 1/30 of second so If you don't have anything to draw, you get black canvas with nothing on it.. so you have to always redraw everything each update...If I don't draw the background , buffer start to blink like hell... so I have to have something to cover that stuff up.
I searched on internet and found nothing much about other solutions for this rendering type.. Tuns of stuff for active rendering but nothing for that Draw and wait method..
I think it's impossible to do that with BufferStrategy. Is there something else to serve for this ? Also is there other source for Graphics g ? On internet was something about calling it directyl from Canvas but I didn't get it running for this. Or am I thinking about it from wrong angle?
You're confusing passive rendering with partial updates. In "passive rendering" you can redraw everything, but you don't do it 30fps. you only do it when something moves. In "partial rendering", you only draw on the part of the canvas that changed.
The two can be put together, so that you only draw what changes, and only when it changes. That's the ideal case.
But passive rendering doesn't work if something is always moving, and partial updates don't work if the whole background is updating constantly.

How to prevent JPanel from repainting everything?

Making a paint-like application that works by saving mouse points in an arraylist. My idea is to have a "points" arraylist with all the previously drawn stuff, and a "temp" arraylist to get and modify the current brush stroke the user just entered. This is necessary as the user can change the color and size, so my idea is to modify the current brush stroke based off what buttons have been pressed, then add that brush stroke to the rest of the picture. I searched around StackOverflow and found some code but cant get it to work how I want to (assuming I found the right code).
#Override
public void paintComponent(Graphics g1) {
super.paintComponent(g1);
final Graphics2D g = (Graphics2D)g1.create();
try {
g.setColor(brushColor);
for (Point point : tempArrayList){
g.fillOval(point.x, point.y, brushSize, brushSize);
}
} finally {
g.dispose();
}
The problem is that I need to clear the tempArrayList for the next brush stroke, which I can do when they change the color/size, but then it erases what was previously there. I am starting to think that I don't even need the "points" arraylist as descibed above because I was hoping that the g1 graphic would just save what the g graphic created.
I guess I just need to figure out how to add the g graphic to g1
Painting is controlled by the Swing API, there is a expectation that whenever paintComponent is called, you will repaint the entire state of the component (as part of your component might have been damaged due to some system event), so the short answer is, no, you can't...however....
You Could...
Paint to a BufferedImage instead and paint the BufferedImage when paintComponent is called
You Could...
Establish a series of "paintable" objects which contain information about what is to be painted and how it is to the painted, including the brush stroke, stroke color and fill color.
These would then be added to some kind of List and "painted" when the paintComponent method is called
Check out Custom Painting Approaches for exampled of painting from:
A List of objects
A BufferedImage.
The examples show how to draw Rectangles of different colours.

Best way to avoid redrawing an entire maze?

I'm working on a project for maze generation using Java, swing, and Java2D. I'm fairly new to Java2D so please excuse me if this question is newbish.
Basically, I have a successfully generated maze. I wish to draw this maze on a custom JPanel that I've set up and properly overridden PaintComponent on. The problem I have now is I currently have the ability to draw the maze, but every time I repaint it disappears. I've solved this by having it redraw the maze every time repaint() is called but this seems horribly inefficient. Since the maze doesn't change why should I have to redraw it?
So my question is this: is there any way to "cache" the drawing of the maze so I don't have to waste cycles redrawing it every time? I can see redrawing it every time for exceptionally large mazes being a major source of slow downs.
Thank you!
Draw the maze to a BufferedImage. Then in your paintComponent() method just paint the BufferedImage. Swing will determine whether the entire maze or just parts of it need to be repainted.
For an example painting onto a BufferedImage see the DrawOnImage example from Custom Painting Approaches.
If the maze never changes, you can initially draw it into a BufferedImage. You can use your same code you wrote for overriding paintComponent by creating a BufferedImage and calling image.createGraphics() on it to get a Graphics2D object. Any painting you do to the Graphics2D object returned from createGraphics() is added to the BufferedImage. You may have to extract your previous drawing code just for the maze into its own function which takes a Graphics2D object and draws to it.
Once you have your maze drawn into the BufferedImage, you can use any of the drawImage() functions in Graphics or Graphics2D. This avoids having to redraw the maze: now you are just drawing the already rendered image.

Java 2D Graphics Rectangles

I'm attempting to make a Java Applet that will allow me to draw a graph data structure in a canvas. I will do this by clicking where I want to create nodes, and clicking the nodes to connect them. The problem is I cannot get the paint() method to behave correctly. I add new nodes to the graph (and squares on the canvas) inside the mousePressed(MouseEvent e) method using,
Graphics g = this.getGraphics();
g.setColor(Color.blue);
g.fillRect(e.getX(), e.gety(), 40, 40);
Everything works fine, until I resize the window, and then all the filled rectangles vanish. I overrided the paint method to just an empty method, but the same thing still happens. I can't add the fillRect commands inside paint() because I don't know what rectangles exist until the user interacts with it using the mouse.
How can I use g.fillRect() inside the mouse listener methods and make them stick?
The problem is the place you're drawing to isn't persistant. At any moment, you can lose everything you've drawn to it. The paint(Graphics) method is called when this happens. You'll either need to repaint the entire picture every time this happens, or you'll need to set aside a canvas to draw to and copy the contents to your applet's Graphics as needed.
Here's how to create and draw to an image:
http://java.sun.com/docs/books/tutorial/2d/images/drawonimage.html
Then, in your paint method, use your Graphics' drawImage(...) method to display the image you've created.
I don't know if I'm reading this correctly, but why not just store the location of the last click in a variable to be painted later, when the paint() method is called?
You've got to override the window resize action listener and call repaint inside of it.
The Graphics is temporary. When a region gets dirty, it will be repainted.
The best way is to create a BufferedImage, paint to it on mousePressed and call repaint.
When paint is called, draw the Image onto the passed Graphics Object. This way you don't need to store the Rectangles and you got a buffer which will improve performance.

Categories

Resources