animate() only called once

24 views
Skip to first unread message

Thomas

unread,
May 2, 2018, 12:13:37 AM5/2/18
to CodenameOne Discussions
I am trying to create a custom component that animates. But it looks like the animate() method of my component is only called once (instead of beeing called at each EDT cycle) and I don't understand why.

Here are the relevant methods of my custom component:

```
 /**
     * {@inheritDoc}
     */
    public void initComponent() {
        if(infinite) {
        System.out.println("Animate");
        getComponentForm().registerAnimatedInternal(this);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void deinitialize() {
        if(infinite) {
            Form f = getComponentForm();
            if(f != null) {
            System.out.println("UnAnimate");
            f.deregisterAnimatedInternal(this);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean animate() {
    System.out.println("Anim called");
        if(infinite) {
            float f = (infiniteSpeed * (reverseDirection?(-1):(1)) * ((float)maxValue));
            if(((int)f) == 0) {
                if(f < 0) {
                    f = -1;
                } else {
                    f = 1;
                }
            }
            value += ((int)f);
            if(value >= maxValue) {
            if (reverseAtEnd) {
            value = maxValue;
            reverseDirection = true;
            }
            else {
            value = (int)0;
            }
            }
            if(value <= 0) {
            if (reverseAtEnd) {
            value = (int)0;
            reverseDirection = false;
            }
            else {
            value = maxValue;
            }
            }
            System.out.println("New value: "+value);
            super.animate();
            return true;
        }
        return super.animate();
    }


 public void setInfinite(boolean i) {
        if(infinite != i) {
            infinite = i;
            if(isInitialized()) {
                if(i) {
                System.out.println("Animate");
                    getComponentForm().registerAnimatedInternal(this);
                } else {
                System.out.println("UnAnimate");
                    getComponentForm().deregisterAnimatedInternal(this);
                }
            }
            else {
            System.out.println("Not initialized");
            }
        }
    }

```

and the output I have in my console with the simulator:

```
Animate
paintComponentBackground finished
Anim called
New value: 3
paintComponentBackground finished
```

As you can see the animate() function is called (so my component seems correctly registered as animated at the parent level). But after that, nothing. The animate() function is not called anymore and my value variable do not change....
I looked at the animated ClockDemo and it looks like pretty similar so I don't understand what is wrong with my code...

Thomas

unread,
May 2, 2018, 12:22:18 AM5/2/18
to CodenameOne Discussions
EDIT: OK looks like calling super.animate() is causing the issue (but it is what is given as example in the documentation: https://www.codenameone.com/manual/animations.html) . If I remove the super.animate() and only return true or false, it works...

Shai Almog

unread,
May 2, 2018, 12:30:56 AM5/2/18
to CodenameOne Discussions
We try to be smart and "deregister" when possible to keep performance/battery usage going. So if a component has its own animation it will try to do that.
You can skip the call for super if the builtin animation doesn't matter or you can re-register the animated if you still need it (it won't add you twice).

Thomas

unread,
May 2, 2018, 12:41:02 AM5/2/18
to CodenameOne Discussions


On Wednesday, May 2, 2018 at 6:30:56 AM UTC+2, Shai Almog wrote:
We try to be smart and "deregister" when possible to keep performance/battery usage going. So if a component has its own animation it will try to do that.
You can skip the call for super if the builtin animation doesn't matter or you can re-register the animated if you still need it (it won't add you twice).

Yes the parent builtin animation doesn't matter (as it is just an "empty" Component without any animated background image or whatsever) . What I don't understand though is why calling super.animate() before returning true in my child custom component animate() function makes this function to only be called once whereas it works well if I don't...
Imagine I had an animated background image in my parent component, how would I do to animate both this background image and my child component?

Shai Almog

unread,
May 3, 2018, 12:54:17 AM5/3/18
to CodenameOne Discussions
Did you explicitly invoke registerAnimated?
If you did it shouldn't be cleared.

Thomas

unread,
May 3, 2018, 12:09:57 PM5/3/18
to CodenameOne Discussions
I called registerAnimatedInternal() in initComponent() yes (and it is correctly called as I have 'Animated' print into my console output). I don't know why it is cleared. Seems like a bug. For now I fix it by removing the super.animate() line (as my ancestor Component do not have any animation anyway) but I will investigate a bit more when I have some time. 

Shai Almog

unread,
May 4, 2018, 12:09:23 AM5/4/18
to CodenameOne Discussions
If you explicitly invoked it deregister shouldn't happen. This could be a bug.

Can you override:     public void deregisterAnimated(Animation cmp)

And place a breakpoint within it. See who invokes it and provide me with the stack trace/line numbers?

Reply all
Reply to author
Forward
0 new messages