There are numerous approaches to style or template JavaFX controls.
Pre-built JavaFX controls are styleable via css.
Pre-built JavaFX controls can also be subclassed to modify their functionality and look and feel. An example is the IntField, which creates a TextField customized to edit only integer numbers.
Often, you can build custom components by placing a bunch of existing controls together in a layout Pane or Group. By parameterizing the method or class which constructs the amalgamated component, you can effectively template custom component construction through code. Here is an example of digital and analogue clock components built using such a method (and styleable via css).
You can also manage the layout of a custom component via different fxml files using the approach in the introduction to fxml document. The fxml could be generated from a using a templating language like velocity, or a few different static fxml files could be written for different layouts. The static or generated fxml can also be served dynamically from a webserver, like a dynamically generated html site if needed.
Another way you can build custom control is the same way which the JavaFX team does it (by creating Skin and Behaviour classes for the control). As of JavaFX 2.2 (and perhaps even in future JavaFX versions), this is most appropriate for library creators, such as those working on jfxtras or contributing directly to the open source control repository of the JavaFX project.
Also note that, in css, you can specify a skin class for a control, for example RadioButton has the following css:
.radio-button {
-fx-skin: "com.sun.javafx.scene.control.skin.RadioButtonSkin";
}
So, one way to customize the RadioButton look as you are considering is:
- Grab a copy of the RadioButtonSkin class source from the open source JavaFX repository I linked earlier.
- Copy it to a new classname (e.g. LinedRadioButtonSkin).
- Modify it to get the look you wish.
- Create a custom css stylesheet for your project.
- In the custom css stylesheet set the
-fx-skin
attribute of the .radio-button
class to use your new LinedRadioButtonSkin class.
As long as your new Skin is implemented correctly and wired up to the existing ButtonBehaviour class similar to how the existing RadioButtonSkin class works, then you should automatically get the same behaviour for your new skin based radio button as existing radio buttons. For example, the button will respond to mouse clicks, keyboard accelerators, touch events, interact with ToggleGroups etc, exactly the same as the existing RadioButtonSkin and be accessible using the existing RadioButton api. That is, the button retains the feel (behaviour) of a RadioButton but can have a completely different by using different internal components, layout and css styling.
If you decide to go the custom skin route and need help on this process, consider contacting members of the jfxtras team and donating your new skin to the jfxtras project.
Caveat
The Skin and Behaviour classes in JavaFX 2.2 are private implementation apis, not publicly supported apis and will change in the future as they transition to public api (scheduled for the next major release of JavaFX - JavaFX/JDK 8) - so if you use these today, do so with caution. Once they transition to public APIs, I expect you will see more information and tutorials on how to create your own controls using these classes.
The package names and api methods will change as the api to build your own controls from Skin and Behaviour transitions from internal private implementation to public api. For example com.sun.javafx.scene.control.behavior.BehaviorBase
might become javafx.scene.control.behavior.Behavior
, so if you create a class extending BehaviorBase, it won't run against a new version of JavaFX until you modify the source of class to reference the new name and api and recompile it.
For this same reason, there will be no good books on this topic until the API is public and final because any example code the book included which was written against the private api would be out of date as soon as api is made public and would neither not compile against the public api, nor execute against the newer version of JavaFX.