Swing: Update Graphics every millisecond? - java

I created a little sketchpad program with basic GUI. I used the paintComponent method. I want to update the graphic being drawn every millisecond. That way, the user can see what they're about to draw before they release the mouse click.
For example, if I'm drawing a rectangle, I want to see the rectangle while I'm drawing it.
If you're confused as to what exactly I'm talking about, open MS Paint and click on the rectangle tool. Draw a rectangle. Notice how it updates continuously, as opposed to after you release the mouse.
I figured that there must be some way I can get it to update my graphics every millisecond. What is the best way to go about doing this? Sorry if this is an easy question, I'm new to Swing! :)

Well you don't update every millisecond.
You use a MouseMotionListener and you update every time a mouseDragged event is generated to redraw the Rectangle.
Check out Custom Painting Approaches for two approaches on how to do this.
The examples show how to draw multiple rectangles by either:
Adding Objects to a List and then repainting each object every time the component is repainted
Painting directly onto a BufferedImage and the just painting the BufferedImage.

Related

Use components as JProgressBar on java game

Been building up a little game in java, already asked a few questions about the usage of JPanel in it, and used them to paint the graphics and the main part of the screens.
Now i have a little doubt about other components. My intention is to add on the corner a pair of bars to show health and mana of an entity (like in a rpg game), and wondered which was the best approach for it.
Thought about making a new JPnale with a pair of JProgressBar to set the ammount of it, but then i wondered if it would be better to paint it completely and fill a pair of rectangles.
I mean, doing a pair of new JProgressBar() for it, or a pair of g.fillRect() and then paint the ammounts.
I guess that easiest is to set the JProgress, as i can set values and text if i want, maybe, but not sure about it and if it would run smoother without overwhelming it with JComponents.
Also, if want to add buttons would be better the JButton, or paint a rectangle and check for containment of the mouse pointer with an event (I have this approach at some points where there is not KeyBinding). Should i change that?
Thank you beforehand :)
I'm writing an answer because i haven't got enough reputation to comment :(
I think is better if you paint it in your graphics engine. Use Rectangles is of course a better idea than use a new JPanel with JProgressBar.
But i think that it's even better if you use Images to build your own Progress Bar.
You can create them or find them on internet.
For example you can take an Image for the Progress Bar Background, and another Image for the Foreground (the part that will fill the Bar). Then you can set their X and Y position and then just change the Foreground Width in relation with the entity health to fill or empty the Progress Bar.

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.

Simple painting

I have an seemingly very simple task at hand. I have a grid (500x500 right now) I want to visualize as it is populated and I want to write a class in Java that makes this easy for me to do. I'm thinking something along the line of:
public class Screen {
...
public void plot(x,y) {
// change the color of pixel x,y to black
}
public void clear() {
// fill the screen with white
}
}
I have been looking around and quickly found Canvas in awt, however from what I have been able to figure out so far, this widget will only allow me to draw on to it by overriding its paint method. This is far from optimal in my case as this will require me to draw the entire grid every time I wish to do just plot one single pixel.
Is there any way to get canvas to just draw a single pixel rather than the entire canvas? Or some other way to accomplish what I look for here?
I would prefer to avoid having to use any external libraries.
You will need to override the paint method to display the entire grid.
However, what you can do is create a BufferedImage that flips the one pixel, and draw that entire image to the component in the paint method, using Graphics.drawImage().
Unfortunately you have to override paint() and render the entire grid every time paint() is called. That's how graphical components work - the windows system/OS may request to repaint the component at any time (eg. when the window is re-shown/resized/moved)

More efficient way of editing images and displaying?

I'm making a Java application that prints an image and allows the user to edit it by drawing on it. Currently, my program listens for mouse dragged and once it is, changes the color of the pixel the cursor is currently on. In order to display the change, I call paintComponent at the end of each mouseDragged loop. Although its working as intended, the image flutters if I move the mouse too quickly.
Is this because I'm calling on paintComponent too many times? If so, how can I make my program work more efficiently?
I was thinking about simply editing the image in memory only and displaying the image every 1/30th of a second or so instead of displaying it after every edit.
Is this because I'm calling on paintComponent too many times?
Once is too many. Instead call repaint() & let it schedule (or ignore) the call to paintComponent().

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