Java Forum / General / December 2007
Animation Problem
James Sarjeant - 20 Dec 2007 11:10 GMT 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
Andrew Thompson - 20 Dec 2007 11:41 GMT > 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)
-- Andrew T.
James Sarjeant - 20 Dec 2007 13:49 GMT Apologies for the double post but I need to get this sorted James
> > Hi all, > > [quoted text clipped - 8 lines] > -- > Andrew T. Andrew Thompson - 20 Dec 2007 14:14 GMT >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>
 Signature Andrew Thompson http://www.physci.org/
James Sarjeant - 20 Dec 2007 13:55 GMT Apologies for the double post but I need to get this sorted to meet the deadline James
> > Hi all, > > [quoted text clipped - 8 lines] > -- > Andrew T. Stefan Ram - 20 Dec 2007 14:28 GMT >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).
Lew - 20 Dec 2007 14:53 GMT > The behavior of paintComponent() depends on whether this > is a continous animation depending on the time or a [quoted text clipped - 4 lines] > 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.
 Signature Lew
Lew - 20 Dec 2007 14:38 GMT > 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 [quoted text clipped - 6 lines] > 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() > { [quoted text clipped - 41 lines] > 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.
 Signature Lew This post contains two questions, but really both ask the same thing in a different way, so only one request for information.
Matt Humphrey - 20 Dec 2007 14:39 GMT > Hi all, <snip>
> The only > problem is that the scrollForward() method works fine but the playAnim() [quoted text clipped - 5 lines] > 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/
James Sarjeant - 20 Dec 2007 16:05 GMT 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
Matt Humphrey - 20 Dec 2007 16:22 GMT > Hi all, thanks for your help so far. > To clarify, this is a Swing app. Also the images are simply displayed in [quoted text clipped - 14 lines] > 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/
Knute Johnson - 20 Dec 2007 16:25 GMT > Hi all, thanks for your help so far. > To clarify, this is a Swing app. Also the images are simply displayed in [quoted text clipped - 6 lines] > 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.
 Signature Knute Johnson email s/nospam/knute/
James Sarjeant - 20 Dec 2007 17:23 GMT 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
Lew - 21 Dec 2007 03:12 GMT > 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.
 Signature Lew
Knute Johnson - 21 Dec 2007 05:57 GMT >> 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. It's a pesky thing isn't it :-).
 Signature Knute Johnson email s/nospam/knute/
James Sarjeant - 21 Dec 2007 11:36 GMT > > Remember: you think you have gotten away from the advice about the EDT, > > but you haven't. > > 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
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|