JavaFX Composer State Animation Tutorial
The goal of this tutorial is to show how the animation inheritance works.
Before reading with this tutorial you should be able to work with states as described in JavaFXComposerStatesTutorial2.
Create a new project using "JavaFX | JavaFX Desktop Business Application" template.
In the opened design drag and drop a single Label and "Index Buttons" template. In the customizer of the template choose "currentState" state variable as the "Indexed Component" and press OK.
In States list, use "Add State" button to add two new states named "Shown" and "Hidden".
Select "Label" component and open the Details property view for "Opacity". There select "Hidden" state in the list and set "0.0" as the specific value of the "Opacity" property for the "Hidden" state. It should look like this:
At the top of the window, you can see that the animation is specified as "Animate <inherited> in inherited ms". This text represents the first part of the new concept for animation inheritance.
The text can be read as the property for the specified animation is will take:
- The Interpolator inherited from the default interpolator specified for the state i.e. in our case "Hidden" state.
- The Duration inherited from the default duration specified for the state i.e. in our case "Hidden" state.
You may select your own interpolator and/or duration or leave the "inherited" item to specify inheritance. If you press "blue-arrow" button on the right-side of the Duration field, it sets the duration to the "inherited" value.
Let's select the "Shown" state in the states list and enter "0" into the "Duration" field. This way we have said that the "1.0" value will be applied to the "Opacity" property immediately when you switch to the "Shown" state.
Now close the "Details" property view.
In the States-list, select the "Hidden" state and press "Edit" button (or you can double-click on the "Hidden" state in the states-list. The following dialog for editing properties of the states appears:
Among the other common properties, there are two new fields:
- Default Interpolator
- Default Duration
Here you may specify default interpolator and duration of the particular state i.e. in our case "Hidden" state. Or you may leave the "inherited" value to specify that the value should be resolved from the default interpolator/duration specified for a related state variable.
Let's leave the "Interpolator" as "inherited" and set "Duration" to "1000". Note that the "blue-arrow" button on the right-side from the "Duration" field sets the "Duration" value to "inherited".
Press "Ok" button to close the dialog.
Check the states list, the animation description for the "Hidden" state is changed according to your modification:
Select the Label and open Details property view for the "Opacity" property. You can see that the animation for setting "0.0" value in the "Hidden" state is modified as well.
Close the Details property view.
Now let's show the "State Variables" list by pressing "Show State Variable Editor" in the States list in the design view.
The "currentState" state variable should be selected. Press "Edit" button on the left-side toolbar or double-click on the "currentState" item directly.
In the opened dialog, you may edit common properties as well as these new properties:
- Default Interpolator
- Default Duration
These properties specify interpolator and duration assigned to the edited state variable. These values are used as default interpolator/duration of each state of the state variable where "inherited" value is specified.
Note that there are no "inherited" values.
Let's set the "Default Interpolator" to "LINEAR". The state variable edit dialog should look like this:
Press "OK" to close the dialog.
Now the interpolator of both states ("Shown" and "Hidden") is going to be "LINEAR" because their default interpolator is set to inherit from the state variable.
You can check the states/state-variable lists. They should look like this:
Similarly you can open the Details property view of the "Opacity" property of the "Label" component. It should look like this:
Run the application. It should do:
- Press Next button. It should go to "Hidden" state with 1000 ms long linear animation of the opacity of the label.
- Press "Previous" button. It should go to "Shown" state and immediately set the opacity of the label to be fully visible.
Modify Default Duration
The "Duration" of the "Shown" state is "0" since it is inherited from the state variable. Note that the "Opacity" property has the duration for the "Shown" state overridden to "0" value as well.
You may try what happens, when you change the "default duration" of the "currentState" state variable to "2000" ms. If you do so, the default duration of the "Shown" state is set to "2000" ms but the "Opacity" in the "Shown" state will be set at "0" ms.
If you run the application now, you will not find any difference.
Beware of Discrete Properties
Some properties e.g. Node.visible, Label.text or Node.onMousePressed, ... are discrete. This means whatever interpolator you set, they gets modified in running at once at time specified by the "duration".
When you are NOT using 0 ms as the default duration in a state or a state variable, the duration (if not overridden) is used even for these properties. This leads to a common mistake where the "onMousePressed" events are hooked up delayed after a state is changed. The best to prevent it is to set the duration to "0" ms for all states for all discrete properties that are modified at least in one state.