Animation Problem

J

James Sarjeant

Hi all,

I have a program which generates a set of images based on some data and
displays them on the screen in various places based on a counter
representing the steps so step 1, step 2 etc. I want the user to be able to
scroll through the steps 1 at a time by clicking a button or if they press
play, I want the steps to scroll automatically but with a delay in the
middle.



I have created a scrollForward() method which updates everything just once
for the next step in the sequence and for the playAnim() method I call
scrollForward(), then wait for a delay (using the system time and a speed
variable) then scrollForward() again until the end is reached. The only
problem is that the scrollForward() method works fine but the playAnim()
method simply calculates all the steps but only shows the final state of the
images with no intermediate steps. Does anyone have any ideas of how to get
this to work? Due to the nature of the program I cant use a thread, hence
the system time wait method but it just doesnt put the pictures on the
screen. The two methods are below if they provide any insights.



public void scrollForward()

{

if((programCount + 1) < numInstructions)

{

if(compiled)

{

updatePC(true);

updateImages();

}

else

{

showError("Your machine code must be compiled before you can
scroll.", "Compile error");

}

}

else

{

showError("No more instructions to show.", "Input error");

}

}







public void playAnim()

{

while (running)

{

scrollForward();



long current = System.currentTimeMillis();

long start = current + (speed * 250);

while(System.currentTimeMillis() <= start)

{

// wait and do nothing

}

if(programCount < numInstructions-1)

{

running = false;

}

}

System.out.println("end Anim");

}





The scrollForward works fine but as soon as it is run in a loop it works but
doesnt show the images. Any ideas are welcome.



Thanks in advance and sorry this post is quite long.

Cheers

James
 
A

Andrew Thompson

Hi all,

I have a program which generates a ..

...multitude of posts to different usenet newsgroups?

Please refrain from multi-posting, in future.

(X-post to c.l.j.p./h., w/ f-u to c.l.j.p. only)
 
J

James Sarjeant

Apologies for the double post but I need to get this sorted to meet the
deadline
James
 
A

Andrew Thompson

James said:
Apologies for the double post

OK but..
..but I need to get this sorted

..that is not our problem. These groups are not help-desks.
If you require urgent help, it is probably better to hire a
consultant, or contract the services of a help-desk.

Also, please 'post inline' with trimming - placing comments
immediately after the relevant text (and deleting other text)
in replies. It is much easier to follow, than top-posting.

Note that I find questions on animation particularly
fascinating, and had your post to c.l.j.help open a
separate browser window, ready to read after I
checked the new posts to my favorite three groups.

After I noticed the multi-post, I decided I had better
'sort' that first.

But noting your concern to get this matter dealt with
quickly, I will also suggest that code snippets are less
effective for getting help than an SSCCE. More details
here..
<http://www.physci.org/codes/sscce.html>

--
Andrew Thompson
http://www.physci.org/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200712/1
 
S

Stefan Ram

James Sarjeant said:
all the steps but only shows the final state of the

I would like to try to summarize how to do animation.
This is somewhat daring, because I never actually wrote
anything like this myself:

One thread needs to call repaint() repeatedly. Usually
this will be done with the update frequency wanted.

Special care might be necessary if the update frequency
should be »as fast as possible«: Then the time between
two calls of »repaint()« should be significantly smaller
the the run time of a single paintComponent(). This
run time, however, is not known when writing the program.
So, one might measure it at run time and then call
repaint() after 1/20 of it? Multiple calls of repaint()
will be coalesced by Swing when they arrive while
paintComponent() is still running, so that this should
be harmless.

The behavior of paintComponent() depends on whether this
is a continous animation depending on the time or a
stepped calculation proceeding in generations. In the
first case, the picture is calculated for the current time.
In the second case, the next generation is calculated
and then display. Both of which, however, might conflict
recommendations not to do long calculations within the
event-dispatch thread (I don't know how to handle this).
 
L

Lew

James said:
I have created a scrollForward() method which updates everything just once
for the next step in the sequence and for the playAnim() method I call
scrollForward(), then wait for a delay (using the system time and a speed
variable) then scrollForward() again until the end is reached. The only
problem is that the scrollForward() method works fine but the playAnim()
method simply calculates all the steps but only shows the final state of the
images with no intermediate steps. Does anyone have any ideas of how to get
this to work? Due to the nature of the program I cant use a thread, hence
the system time wait method but it just doesnt put the pictures on the
screen. The two methods are below if they provide any insights.

No need to skip every other line in your Usenet source listings. It doesn't
actually enhance readability - quite the contrary, actually. Generally on
Usenet you can and should reduce, but not eliminate, whitespace to balance
compactness and readability. Your indent level of 4 is acceptable, but you
can get away with one less indent level for method bodies, i.e., align the
method-body braces with the method signature and everything within moves one
level left also.
public void scrollForward()
{
if( (programCount + 1) < numInstructions)
{
if(compiled)
{
updatePC(true);
updateImages();
}
else
{
showError(
"Your machine code must be compiled before you can scroll.",
"Compile error");
}
}
else
{
showError(
"No more instructions to show.",
"Input error");
}
}

public void playAnim()
{
while (running)
{
scrollForward();
long current = System.currentTimeMillis();
long start = current + (speed * 250);
while(System.currentTimeMillis() <= start)
{
// wait and do nothing
}
if(programCount < numInstructions-1)
{
running = false;
}
}
System.out.println("end Anim");
}

The scrollForward works fine but as soon as it is run in a loop it works but
doesnt show the images. Any ideas are welcome.

Whatever thread runs playAnim() is going to choke the system, needlessly.
Don't do busy-wait loops like that. Use a Timer, javax.swing.Timer if this is
a Swing app.

If this is a Swing app, then what's with the System.out.println() call, mm?

Not to digress too much, but logging should use a logging library
(java.util.logging, org.apache.log4j) and log things that matter, at the
appropriate Levels.

Is this a Swing app?

Assuming that it is, if you try to update components off the Event Dispatch
Thread, the EDT, you likely won't see any updates of the screen until after
the program ends. If you try to perform extensive calculations or other
activities on the EDT, you likely won't see any updates of the screen. What
you must do is calculate, retrieve, transform, fold, mutilate and spindle off
the EDT, then post /faits accomplis/ to the EDT for nothing but display
updates, i.e., paintComponent() calls. (Event handling I leave as a separate
topic.) With judicious use of a javax.swing.Timer you can force periodic
updates to the display of image during the background construction of the image.

OK, that does pull you into the world of event handling. You're going to have
fun.
 
M

Matt Humphrey

James Sarjeant said:

The only
problem is that the scrollForward() method works fine but the playAnim()
method simply calculates all the steps but only shows the final state of
the
images with no intermediate steps. Does anyone have any ideas of how to
get
this to work? Due to the nature of the program I cant use a thread, hence
the system time wait method but it just doesnt put the pictures on the
screen. The two methods are below if they provide any insights.

Your code is executed in the EDT (Event Dispatch Thread). While the EDT is
busy performing your method it is not available to update the screen, read
other inputs, etc. The standard solution for this is to fire off the
animation in a separate thread. Because you cannot use that technique
(please say why--it's a very unusual constraint given that the JVM is full
of threads anyway) you will probably have to use active rendering.

http://java.sun.com/docs/books/tutorial/extra/fullscreen/rendering.html

I havn't used this mode, but it is technically possible. There may also be
other ways to achieve what you want to do.

Matt Humphrey http://www.iviz.com/
 
L

Lew

Stefan said:
The behavior of paintComponent() depends on whether this
is a continous animation depending on the time or a
stepped calculation proceeding in generations. In the
first case, the picture is calculated for the current time.
In the second case, the next generation is calculated
and then display. Both of which, however, might conflict
recommendations not to do long calculations within the
event-dispatch thread (I don't know how to handle this).

MVC.

Not the next generation of plumbing plastic, the answer to all things Swing is
"Model-View-Controller".

The state of the animation, generational or time-based, is the model. (Well,
one of them.) It is calculated off the EDT. On its own thread (group). Not
on the EDT.

Periodically the EDT wakes up and dips in to the model waters for a refreshing
draught of visible results. It requests model state for purposes of painting.

If the model is generational then the view (that's the part on the EDT) just
takes a snapshot of whatever generation is ready, and preps it for
paintComponent(), or repaint(), or whatever.

If the model is time-based, you probably need some event stitching. Well,
events help the generational model, too.

Anyway, the animation model runs as fast as desired, or as close as possible,
in its own thread.

Perhaps the animation runs a frame at a time, based on a javax.util.Timer
telling it when it's time to make another frame. Maybe it runs at odd times
depending on when another logic model fires an event. Maybe it runs on demand
when the view asks for an update, again possibly using event notification to
make that happen. Maybe the animation model fires events when it has done
something important (e.g., completed a frame). (I'm a little suspicious of
approaches where the animation model pushes rather than having the view pull.
I don't know if that suspicion is rational - I'll have to investigate when I
have some time. We could have a subthread on that.)

Note that by this approach the animation model is decoupled from the view, the
timing engine and other logic models, both conceptually and operationally.
 
J

James Sarjeant

Hi all, thanks for your help so far.
To clarify, this is a Swing app. Also the images are simply displayed in
JLabels dotted around the GUI. The updateImages() method simply takes the
latest set of images based on the step counter which is changed in
updatePC() and called programCount.

As for the thread issue, the user may or may not run the animation, or the
scrollForward() or the other scrollBack() methods. No aspects of this
program so far are in a thread other than the default ones and for
simplicity sake it would be best to keep it that way if at all possible. The
scroll methods work just fine by changing the ImageIcon of the JLabels and,
unless I am mistaken (which is possible), it should work with a delay
between method calls??

I'm not ruling out any ideas though so keep them coming if you can. If you
need any more information then just ask.

Cheers
James
 
M

Matt Humphrey

James Sarjeant said:
Hi all, thanks for your help so far.
To clarify, this is a Swing app. Also the images are simply displayed in
JLabels dotted around the GUI. The updateImages() method simply takes the
latest set of images based on the step counter which is changed in
updatePC() and called programCount.

As for the thread issue, the user may or may not run the animation, or the
scrollForward() or the other scrollBack() methods. No aspects of this
program so far are in a thread other than the default ones and for
simplicity sake it would be best to keep it that way if at all possible.
The
scroll methods work just fine by changing the ImageIcon of the JLabels
and,
unless I am mistaken (which is possible), it should work with a delay
between method calls??

I'm not ruling out any ideas though so keep them coming if you can. If you
need any more information then just ask.

From what you describe, I really recommend that you look at the
javax.swing.Timer class. It's very simple to use and you can control whether
it runs or not. All you really want it to do is update the label images.
(Active rendering is overkill) Pull up the Javadocs and hvave a look at
this tutorial http://java.sun.com/products/jfc/tsc/articles/timer/

Matt Humphrey http://www.iviz.com/
 
K

Knute Johnson

James said:
Hi all, thanks for your help so far.
To clarify, this is a Swing app. Also the images are simply displayed in
JLabels dotted around the GUI. The updateImages() method simply takes the
latest set of images based on the step counter which is changed in
updatePC() and called programCount.

As for the thread issue, the user may or may not run the animation, or the
scrollForward() or the other scrollBack() methods. No aspects of this
program so far are in a thread other than the default ones and for
simplicity sake it would be best to keep it that way if at all possible.

You can't. If you wait on the EDT it isn't going to update the GUI.

The
scroll methods work just fine by changing the ImageIcon of the JLabels and,
unless I am mistaken (which is possible), it should work with a delay
between method calls??

No it won't.
I'm not ruling out any ideas though so keep them coming if you can. If you
need any more information then just ask.

There are a million ways to do this but probably the easiest is with the
javax.swing.Timer (I think somebody else already said that). That way
you can do the updates on the EDT (which is required) and the timing
somewhere else.
 
J

James Sarjeant

Thank you so much everyone, it worked with the javax.swing.Timer events.
Still got other bugs to iron out but thats a huge hurdle overcome.
Thanks again
James
 
L

Lew

James said:
Thank you so much everyone, it worked with the javax.swing.Timer events.
Still got other bugs to iron out but thats a huge hurdle overcome.
Thanks again

Remember: you think you have gotten away from the advice about the EDT, but
you haven't.
 
J

James Sarjeant

Remember: you think you have gotten away from the advice about the EDT,
It's a pesky thing isn't it :).

I never think I have escaped anything with Java. When they teach it in uni
or schools it always sounds so simple but it never is.
Thanks for the heads up about the EDT though. I think this application will
have many periods with that rearing its head

James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top