JavaFX Composer States Tutorial
This document is written for Preview 1 release and there might be small changes in the screenshots. Still the tutorial is doable even in the new release.
In Preview 2 release there are two changes:
- added a concept of an animation inheritance - for details, read State Animation Tutorial
- editing of Colors is changed i.e. the "Text Fill" property of a Label - read the Colors section in the New In Preview 2 document for manual how to edit them
First you have to have a project with a design file opened e.g. create a new project using "JavaFX | JavaFX Desktop Business Application" project template.
For the purpose of the tutorial:
- drag and drop a Label to the design
- change its "text" property value to "Master State"
- drag and drop a Button to the design
- change its "text" property value to "Next State"
- click on "Generate" button at "Action" property, choose "Generate: Go to next state" template. The buttonAction function is generated. Change "currentState.next()" call to "currentState.nextWrapped()".
The goal of this tutorial is to explain states in details and as well as possible work-flow and tools for working with them.
A new design is always created with a single state called "< master >" as can be seen at the image above.
Everything you design in this state is created and setup when you start an application. You can work with components and set their properties as usual.
Each component has properties that are editable in Properties window. By default, properties has "Default" values. If a property is initiated after its creation or changed by an user in the master state, then the property has "Master" value set.
Creating a New State
You can create an additional state to your design. A state represents a set of property values that set to particular component properties at once. All property values for non-master state are always inherited from the values that are set in Master state. If a property value is not set in master, then it take the default value.
To create a new state, press "Add" button.
The following dialog should appear. It allows you to set:
- the name of the new state
- whether to "Inherit from master state" or duplicate existing state
- whether to this new state as the initial one
The best is to choose a unique name of state. Duplication is disabled since there is no other state except for Master state. When a state is set as starting one, the final application will automatically switches to this state right after the scene is created from the values set in the Master state.
Therefore change the state name to "Red" and leave the rest unchanged. Now you have a first state called "Red" which is automatically selected.
Changing Properties in a State
When a state is selected, then whatever you do is recorded just for the particular state e.g.:
- a new component will be added as invisible in all states except the selected one
- a new value of a property will be set just for selected state.
Select the Label and in-place edit the "text" property to set "Red State" value. Similarly edit the "Text Fill" property to set "red" color. Note the icon next to the property values which indicates that a particular property value is override in the selected state.
Note that the Preview 2 the colors are edited as resources. Therefore you have to press "Add" button and choose "Color" from the popup menu. This way you have created a Color resource and assigned it to the "Text Fill" property. Now press "Edit" button to select the color and slide the sliders to set "Red" color.
The result should look like this:
You can select the "< master >" state to see that the design is unchanged in the Master state. Selecting the "Red" state again will return to the "Red" design.
Duplicate a State
Now you can create a new state:
- Press "Add" button again
- Enter "Blue" as the state name
- Choose "Duplicate of" radio button and "Red" state in the combo box
Now you have Master, Red and selected Blue states.
During the creation of "Blue" state, all property values that has been modified in "Red" state are now copied to the "Blue" state. The rest of the properties are inherited from Master state.
Therefore the Label is still labeled with "Red State". Change its "Text" and "Text Fill" to "Blue State" value and "blue" color.
Now we would like to add an effect to the animation to the scaleX property of the Label.
To do so, press the "Transform" category in the Properties window and scroll down to the Transform properties of the Label.
Now select the "Blue" state and enter "1.5" as the value of "Scale X" property of the Label in this state.
Then press the icon on the right side of the "Scale X" property of the Label. This will open a Details dialog that allows you:
- to see values and animations of the property for each state at one place
- to set the property value for multiple states - just multi-select the states in the list and enter the new value
- set a simple animation using "interpolator" combo box "duration" text field in the upper-right corner
- set the value using a custom code (or reference to a field) by selecting "Use value resolved from field:" and entering the custom code or a field name to resolved the value from
- bind a property (described in another tutorial)
- reset the stated value to master or master value to default
- pushing the value from selected state as the master value
In the list you can see that the "Scale X" property value is immediately set to "1.0" except for "Blue" state where it is "1.5".
To set the animation, press "Select All" button to select all non-master states i.e. "Red" and "Blue". In the "Animate" combo box select "Linear" and enter "500" to the text field of the right side.
This means that you have set an simple linear animation to the "Scale X" property when the Red or Blue states is activated.
Note that setting the animation just to a single e.g. Blue state would make the animation visualized only when you switching from any state to the "Blue" state. In any other case e.g. switching to "Red" state, there would not be any animation and the value would be set immediately.
Note that the animation is not visualized in the design and can be seen in the runtime only.
Note that the Master state cannot have animation set since the value are just taken as initial value for component when they are created.
Running the Application
Switching between Master, Red and Blue states will show you different text and color of the Label.
Now run the project using the "Run" icon in the main window toolbar. The application will appear as a window.
The window will be initially shown with "Master State" Label which will be immediately replaced with the "Red State" Label. This is due to the fact that the Master state is takes as initial design of your scene and right after the scene initialization, the design is switched to the start state.
Pressing "Next State" button will switch the design between the "Red" and "Blue" states so the Label will be changing and animate its x-scale.
If you have many property values changed in various state. You may switch to "Review" mode by pressing "Review" button in the Properties window.
This will switch the view of the properties to list of properties that has been modified any any time (master or any other state). For each property, it prints all state where the value is changed as well as the its value and animation. Similarly it show whether a custom code is used or the property is bound to a custom expression.
Here is how the review of the Label looks:
Visibility of Components
By default all newly created components added to the design but their visibility it set according to the selected state:
- If a Master state is selected, then the component is visible in the master and the visibility is not overridden in any state so it is automatically inherit as "visible" in all states.
- If a non-master state is selected, then the component is INVISIBLE in the master and the "Visible" property value is overridden to "true" in the selected states only. This make the component visible on in the state which has been selected when the component was added.
It is better to minimize the load of property changes that occurs during a state change. Therefore edit the properties in the Master state as much as possible and only the value that are changed in a particular state should be edited in non-Master state.
The visibility is set to all components according to selected state even for the ones that are added to the container which are visible in a particular state only.
In this case it is better to use the following pattern:
- Have a Panel with two Labels that should be visible in the "Blue" state only.
- Select the "Blue" state create a Panel in a Design by drag and drop it from Palette to Design. This will make the Panel visible in the "Blue" state.
- Select the "Panel" and invoke "Design selected container" popup menu action in the Design or Navigator.
- This will switch the design editor from design the Scene to design the Panel.
- Select "< master >" state.
- Add the two Labels by drag and dropping them from the Palette to Design.
- This way you have a container which is visible in "Blue" state only and you can initial and design its Labels in the Master state. This would reduce the inefficient code execution when states are changed.
Note the best is to do as many work in the Master state as possible.
Set Component to Master
Sometime may get to a point where you realize that you have added and modified a component in a state which it should be modified in the Master state instead.
In that state, select the particular component and invoke "Set Component as Master" popup menu action in Navigator or Design.
This action would push the values in the selected state as the master values.