Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2.0 - style / template existing control

I'm very experienced with WPF and new to JavaFX 2.0. I'm about to move a Silverlight project to JavaFX 2.0. Two Apress books and several threads couldn't answer my questions (maybe I fail to see or understand the answers, because of my WPF influenced expectations).

What I need is a control with RadioButton functionality but an completely different UI. My RadioButton has a text, an image, no button, a line (rectangle) below the text. If the RadioButton is not selected, the text and image are transparent, the image is grayscaled and the rectangle not visible. If it is selected, the text and image are opaque, the image is colored and the rectangle becomes visible (all changes via animation).

I know how to skin an existing JavaFX 2.0 control, but I don't know how to style/skin the RadioButton this way.

In WPF I simply create a new template for my RadioButton style... as I mentioned, maybe these WPF influenced expectations for JavaFX 2.0 are my hurdle.

Thanks...

Edit:

Seems like it is not possible to create another template for existing controls (?): JavaFX 2.0 render controls inside control

So what will be the best way to implement my RadioButton? I bother about the ToggleGroup...

like image 856
thinkU Avatar asked Sep 12 '12 07:09

thinkU


1 Answers

There are numerous approaches to style or template JavaFX controls.

  1. Pre-built JavaFX controls are styleable via css.

  2. 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.

  3. 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).

  4. 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.

  5. 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.

  6. 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:

  1. Grab a copy of the RadioButtonSkin class source from the open source JavaFX repository I linked earlier.
  2. Copy it to a new classname (e.g. LinedRadioButtonSkin).
  3. Modify it to get the look you wish.
  4. Create a custom css stylesheet for your project.
  5. 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.

like image 168
jewelsea Avatar answered Oct 30 '22 13:10

jewelsea