• Post Reply Bookmark Topic Watch Topic
  • New Topic

Circle Oval increase size and on a timer

 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone,
I have a task in school to create a circle that increase from inside to the outside and always getting bigger while the older one is gone.
I must have a timer for the increase.
I already have a code but my problem is that I don't know how to stop the loop.
Any good advice? Please note I am a beginner so a pseudo code will help.
Here is my code:

 
Rob Camick
Ranch Hand
Posts: 2701
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1) Don't use Thread.sleep(..) in a painting method.

2) Don't invoke repaint() in a painting method. This will cause an infinite loop.

3) Don't increment the sizeX/Y variables in the painting method. You can't control how often Swing repaints the panel. Instead you should have a method like "incrementSize()" that will increment the variables. Then you invoke repaint().

4) To do the animation you should be using a Swing Timer. When the Timer fires you simply invoke your "incrementSize()" method.

I don't know how to stop the loop.


Create a variable that keeps track of the number of times the Swing Timer fires. So in the actionPerformed code you increment this variable. When the variable reaches the maximum you stop the Timer.

 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its kinda funny cause in my study books and in the task that I got from school they tell me to invoke repaint() and to use the Thread.sleep(..) and they did not teach about the incrementSize() method.
Thanks for the advice's thought and I will search to make it work with your tips but I am afraid the teacher will fail me since I will not use what I am required.
 
Rob Camick
Ranch Hand
Posts: 2701
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
in my study books and in the task that I got from school they tell me to invoke repaint() and to use the Thread.sleep(..)


That kind of design can be used, but NOT in the painting methods.

A painting method is for painting only. It is NOT used to determine program logic or flow. By using Thread.Sleep() you are controlling the flow by telling the program to stop executing. By invoking repaint() you are adding logic by telling the component to repaint itself in an infinite loop.

The painting code should be fast and efficient and should be consistent every time Swing determines the component needs to be repainted.

The code in a painting method should only be related to task of painting itself based on the properties of the object. The painting code should NOT change the properties of the object. Only you programming logic should change the properties.

I suggest you take a look at the "table of contents" from the Swing tutorial link I gave you. There are section on "Custom Painting" you should look at. The section on "Concurrenty in Swing" is more complicated by also very important to fully understand how Swing works with Threads.
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the explanation and I will take a look at the "table of contents" from the Swing tutorial.
I didn't even know that there is other timer possibility
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have found a solution. My only problem is when I press the x to close it, its not working.
Why is that and how can I fix it?
Here is my code:
 
Darryl Burke
Bartender
Posts: 5155
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have two while loops that do nothing, and as soon as w exceeds 400, the do-nothing loop ties up the EDT so it can't do anything else -- not even respond to clicking the close butotn on the JFrame.

Why did you think you needed those loops anyway?
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The loop increase the size of the circle until its 400 so that it will not continue to grow.
 
Rob Camick
Ranch Hand
Posts: 2701
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My only problem is when I press the x to close it, its not working.


It closes fine for me when I click on the close button.

I have found a solution.


It doesn't work for me. I don't see the oval and I don't see the animation.

The reason I don't see the oval is because you add the panel to the frame AFTER the frame is visible. In this case the size of the frame is (0, 0) so there is nothing to paint. The order of your code should be:



The reason there is no animation is because of the loop in the ActionListener. The point of using a Timer is that it is the loop. The Timer will get invoked every 50ms and then you increment the width/height by 1 each time the Timer is invoked. When you reach the maximum size you stop the Timer.

Also, you should probably start the Timer AFTER the frame is visible. So you can add a method to your class like "startAnimation()". Then you can invoke this method after the frame is visible.
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It works for me just fine... I don't know why you can't see the animation.
And I can close it but when the animation is done I can not close it so I just added a command to exit when the loop gets stop on 400.
 
Rob Camick
Ranch Hand
Posts: 2701
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It works for me just fine...


You must be using a different OS. I'm using JDK8 on Windows 7.

If any of your code is working it is lucky because the code is designed wrong.

I don't know why you can't see the animation.


I explained why. You have NOT implemented the animation logic correctly.

You have loops that increment the w/h values but you never repaint after you increment the value. The component will repaint itself automatically so I have absolutely no idea how you see animation.

I gave you suggestions on how to implement the Timer and the animation correctly. If you want the code to work on all platforms I suggest you follow the suggestions. If you implement the animation correctly you will also solve you close problem.
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your reply and for helping me out, I appreciate it!
Yes I am using older version.
Is that what you meant? now the circle is not increasing, why is that?
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ops I wrote x++ and y++ when I should have written h++ w++
Heres my code and its working is it okay now?
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its working okay for me, is it working for you as well?
 
Rob Camick
Ranch Hand
Posts: 2701
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, the code works, but once again the design is not very good.

1) You should not be using static variables. the x/y variables are only required for paint, so then should be defined when then are used in the painting method
2) The w/h variables are properties of the class to control the size of the oval and should be defined as instance variables of the class and they should NOT be referenced outside the class.
3) The animation is a property of the class, not the main() method. As I suggested before you should be using a Timer to do the animation.
4) The oval paints outside the bounds of the panel. When you do custom painting the component should determine its own preferred size. Read the Swing tutorial on "Custom Painting". Once you add the component to the frame you can then use the pack() method (not the setSize() method) to determine the size of the frame based on the components added to the frame.
5) From a technical point of view all Swing components should be created on the Event Dispatch Thread (EDT). Read the Swing tutorial on "Concurrency in Swing".
6) You are adding two CircleSize() panels to the frame.

Below is a simple template you can use to create simple GUI's. This is based on the demo examples you will find in the Swing tutorial:

1) the main() method will never change
2) the createAndShowGUI() will basically stay the same except for the class that you add to the frame.

I left the methods empty for you to fill in:

1) paintComponent() is for your custom painting
2) getPreferredSize() is for the size of your panel so the frame.pack() method will work properly
3) actionPerformed() is for the code that executes every 10ms when the Timer fires. You will need to increase the size of the oval and then repaint the panel. You will also need to stop the Timer at your desired size.
4) startAnimation() is to start the animation of the circle growing. You could forget about this method and start the Timer automatically in the constructor of the class. In this case you may want to set the initial delay to 500ms to wait until the frame is displayed.




You basically already have all the logic required from your previous examples. Its just a matter of putting the right code in the right method.
 
Piet Souris
Rancher
Posts: 1641
36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Eli,

some years ago, when I had just learned a bit of Java and Swing, I set myself
to convert some old BASIC demo's that I had to Java. One of these demo's involved
moving circles. Here is a simplified version, that also demonstrates many of the points
that Rob made. In the version that I have the circles do not overlap as they do here,
but anyway: have fun.

Greetz,
Piet
 
Eli Kook
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you guys for your tips and advice!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!