• Post Reply Bookmark Topic Watch Topic
  • New Topic

Trying to make a simple graphic object move across a frame and look like an animation.

 
Iv Stan
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello guys,

I am another greenhorn learning Java and trying things out. Below is the code I wrote for a SWING event handling exercise and what I am trying to accomplish there is the following:

1. When "Show Object" button is pressed -> The program will just show a simple graphical object in the top left corner of the frame
2. When "Move Object" button is pressed -> The object will start moving towards the bottom right corner looking like an animation is played

It goes as simple as that, but I have an issue with the moving. After pressing "Move Object", instead of object moving in an animated fashion, it will disappear for a while, the program will look like stuck and then the object will appear on the bottom.

If I don't use buttons and event handlers and just put the FOR LOOP inside the setupWidjets() method it works as expected.

I tried a few quirks, also debugging to see what is going on at runtime, but nothing looked wrong to me. It is just not working the way I want when introducing the buttons and inner classes for event handlers. I feel like there is something with the Thread.sleep(), but I don't have the java thread knowledge yet. Any help would be appreciated.

 
Campbell Ritchie
Marshal
Posts: 52581
119
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

I shall move you to our GUIs forum.

Don't use Thread.sleep() in Swing. Read about threads in Swing in the Java™ Tutorials. Use a javax.swing.Timer instead. Set the timer to fire maybe once every 20ms or every 40ms, but not faster because it takes a few milliseconds to repaint your display. Add a Listener which moves your animation every time the timer fires.
Why are you calling panel.setVisible(false)?
Don't call repaint on the panel. Call repaint on the frame.
Give the inner classes private access; you don't need them outside this class.
Give the paintComponent method protected access. Its first line shou‍ld read:-
super.paintComponent(g);
That will remove anything from the previous round of painting.
Why are you using a black square? Why not simply write
g.setBackgroun(Color.BLACK)?
 
Piet Souris
Rancher
Posts: 1635
36
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Iv,

well, there are some things that you do that shouldn't... but these are easy to repair.

Firsr of all, and most important: make sure that your gui-code runs on the EDT! Although I cannot recall ever having giving me any problem, start with this in your 'main' method:


Since the gui-code now runs on the EDT, something that you really must not do is to invoke: Thread.sleep! That will make your gui very sluggish.
I'll show in a minute how to do that in a much better way.

Next: you do not see your ball move. strangely enough! Yet there is plenty of activity going on. To show this, make your Move-actionListener like this:

and although your ball is not moving, in the output you see all the coordinates being calculated.

The cause of this is that all the repaint-commands are made in one for-loop on the EDT itself. The repaintmanager now compresses all these different redraws into just one redraw, the final one, and thaat is why you see the ball jump to its location.

So, how to improve this? Well, by using a Swing-timer. Add such a timer as a member to your object, and add an actionlistener to it that calculates the new coordinates and then calls repaint on the panel.
For instance:

In the updateBallPosition, you update the ball coordinates and redraw your panel. If the ball gets outside of the panel, make the timer stop.
Then, in your actionCommand on the Move-actionlistener, just start the timer.

Now you'll see a nice moving of the ball...



 
Fred Kleinschmidt
Bartender
Posts: 457
3
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Don't call repaint on the panel. Call repaint on the frame.

Why? The only thing that is changing is the panel. There is no custom painting being done on the frame If there were multiple panels in the frame, and only one of the panels is going to be modified, there is no need to repaint the other panels unless there is a change in size.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!