More efficient way of editing images and displaying? - java

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().

Related

Is there a way to continue to add graphics on a JPanel without having to redoing present graphics (ie. using the repaint() method)?

I've currently rewritten paintComponent() to paint three dots on my JPanel when the program begins to run. Each time the user presses a button I would like to add another dot. I understand I can keep a list of objects as a field and have paintComponent() iterate through that and paint each object, but I plan to have 1000s of iterations (this is the Chaos Game) and iterating through a large list each time I repaint can get costly in terms of time. I would like to avoid this. Any suggestions?

Swing: Update Graphics every millisecond?

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.

How to get mouse position and buffer?

How do I get the mouse position. I have tried:
int mouseX = MouseInfo.getPointerInfo().getLocation().x;
int mouseY = MouseInfo.getPointerInfo().getLocation().y;
But that does it for the whole screen. Anyway to do it relative to the JPanel/JFrame
If I'm only using Graphics JFrame and JPanel that is being repainted every millisecond, should I have buffers? Or will it be fine?
How do I add a mouseAcionEvent only to the frame so it gets X() and Y() of mouse but only in frame?
Use a MouseListener instead of MouseInfo. MouseListener will trigger events which are contextual to the component which raised them, which means you won't need to translate the events into the component space as the event will already be converted to within the component context.
See How to write a mouse listener for more details
How should I update my game rePaint() every millisecond or another way?
Use a javax.swing.Timer...
See How to use Swing Timers for more details...
Should I use buffers?
That will depend. Swing components are already double buffered, but if you use a more complex timing mechanism (AKA game loop), you might find it useful, even to roll your own.
I, personally, would start simple
How can I improve the way I thought out my code in the first place? Is it right having 10 loops or only all in 1 to reduce lag ect.
There are probably lots of things, but start with broader idea...
Breakdown entities to their own responsibilities, for example, the player should know where it is and how it should be painted. It could even know how it's suppose to move based on the current state of the game. This way you could create any number of entities, all with there own set of rules which are isolated and easily updated.
Devise a controller mechanism which is responsible for taking in keyboard and mouse events and simply updating the current state of the game model. That is, rather than going "the user pressed the 'left' key, move player to the left", it would simply raise a flag in the game model that the "left" state has been triggered (or untriggered) and the engine would, on the next update loop, ensure that each entity knew about the change
Don't use magic or hard coded numbers, instead provide some kind of ability to scale the scene. For example, you could decide what is shown on the screen based on the size of the window...

Stop clearing graphics on repaint();?

I'm creating a simple Breakout game and I've encountered a couple of problems.
First off, I need to render the bricks, the paddle, etc... I need to generally render everything on the screen that's needed. However, I don't want, for example, the bricks to continuously render; you can see where the render is occurring as it happens. There's a flash of white.
So, my question is: is it possible to render only certain objects, or more specifically, only render what needs to be rendered?
Every time I call repaint(); I don't want the whole screen to clear and repaint.

Grid building for Connect Four gui

I have been able to create a grid using an image file (serves as the empty circles), a loop, and GridLayout, but I am well aware that there's more functionality needed (like for dropping the token, though no animation is necessary yet) so I scrapped it and now I'm back to an empty grid. I am stuck and I'm not really sure how I can accomplish this. My code is a mess at the moment so I'm not sure if it'd even make sense for me to post it.
My main problem is how to build a grid, which will then just be filled with a solid color (I'm cancelling using an image file, it seems a little more complicated as far as I'm concerned) with empty circles, that I will be able to fill up with an image file of a token once the player clicks on a button that corresponds to the column he chose (and then reset everything after the game is over). In other words, a rectangle of solid color and with empty circles to be filled up by tokens, but not with solid color, but an image file.
I have been trying to familiarize myself with paint() but I only started learning GUI last week so there are still likely some more things I'll have to learn to probably understand it in a considerable degree.
I am running out of options tantamount to my knowledge of GUI (Swing in particular) and I have been trying to work on this for a week now.
Any hints?
There are multiple possible ways to solve this, but one easy one is to give a JPanel a GridLayout, and then fill it with JLabels with ImageIcons that show empty circles. When the column is selected, the appropriate JLabel is given a new ImageIcon via setIcon that shows a color filled circle.
Also,
Always strive to separate your program logic code from your GUI code, since the better your separation, the easier will be your ability to debug and enhance.
Work on small problems one at a time. Don't move on to the next problem until the current small step is solved.
Work out your logic and ideas on paper first before committing it to code.
Don't "work with paint". If you need to do Swing graphics, you'll want to override a JPanel or JComponent's paintComponent method. The paint method also concerns itself with drawing borders and children, and so overriding it can have nasty and unexpected side effects on these. Also paint is not double buffered by default, and this can lead to bad animation once you start working with animation.
Edit
You state in comment:
Will it be okay to use JButton though? Because that was what i used during my first attempt. I can use setIcon with it too right?
Do you mean use a JButton instead of a JLabel? That would work, and yes you can call setIcon on JButtons, but would make all your rectangles look like buttons. So if that's OK, then do it. Otherwise, you could still use JLabels, and then create a row grid of JButtons to put below or above your game grid, and then have the user press those buttons, and in their ActionListeners have them change the icons of a JLabel in the selected column.
But having said this, I mainly recommend that you use what works best for you. The learning will be in the creating, no matter what you create.
Edit 2
You ask:
do you think it'll be possible/a nice approach to store jlabels in an array and then lay them out in a panel?
Absolutely, either an array of JLabel[] or a List<JLabel> I think is not only possible but in fact essential for this to work well. I think that you're definitely on the right track here.

Categories

Resources