AW: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
robert.zenz at sibvisions.com
Tue May 19 08:39:28 UTC 2015
> The intention is to move many JavaFX control skins into the appropriate
> public package, most probably javafx.scene.control.skin. There is no
> intention to also move the related behavior classes, since these will
> be handled separately as part of Project Two below.
> Project Two: Improve support for input mapping
There is a need to have access to the behaviors as well, not only the skins.
The skins and behaviors are very tightly coupled, extending a control without
extending the behavior is possible but is not intended according to the JEP,
it also allows to easily fix bugs which might be encountered.
Before I give some examples, I'd like to tell you our exact usecase.
We provide an Enterprise Application Framework called JVx, the good thing about
is that it provides a "write once, run anywhere" approach by providing a basic
UI toolkit that can be ported to all kinds of technologies (Swing, Vaadin and
JavaFX being the currently supported ones). This means that we have a fixed set
of features that every GUI toolkit that we port to should be able to provide.
So you can imagine it as four layers:
1. Our UI toolkit classes.
2. Implementations of the needed interfaces.
3. Extensions of the GUI toolkit.
4. The GUI toolkit itself (f.e. JavaFX or Swing).
This approach allows us to transparently fix bugs and add missing features
of the GUI toolkit in the extension layer, without the client or user noticing
while working with JVx.
Enough of that, some examples:
* RT-40149, TabPane does misbehave if the last tab is disabled. This was only
possible to fix easily at the behavior level. Not having access to
the behavior would in this case mean that we would need to fix that at
the control level...which means a lot of code for intercepting keys and
* Additionally we added the possibility to deactivate the Ctrl+Tab combo on
the TabPane, which was very easily and cleanly done in the behavior.
* RT-40623/RT-40269, change the values of a Spinner with up/down keys and
the mousewheel. Adding this features was done in the behavior.
I'm sure that the JFXtras and efxclipse projects have very similar requirements
regarding access to the behaviors.
There is an additional "problem" in there, most skins have the hardcoded
dependency on their behavior counterpart. This makes it nearly impossible
to only extend the behavior part of the control. Currently we need to resort
to reflection to change the behavior of the skin at runtime to achieve this,
which is, as you can imagine, a solution I'd like to get rid of yesterday.
Example, you want to change something in the TabPaneBehavior.
The control creates the TabPaneSkin with createDefaultSkin(), the skin
instantiates the TabPaneBehavior in its constructor. You can extend the control
and override createDefaultSkin() to create your own skin. But if you now want
to use an extension of the TabPaneBehavior, you have to resort to reflection,
1. Not calling the skin constructor is not an option, as there is a lot
of setup done there, but it instantiates the behavior it wants directly.
2. Writing your own skin from scratch is possible, but a lot of (duplicate)
3. Copy the sourcecode of the skin and behavior and fix it in your project,
which is something to stay away from because it creates unnecessary
duplication. Also you need to update the copied code with the new versions
with every JDK release. Then there's also the license question and so on.
4. Filing a bug/feature request is the correct way of action, however waiting
for it to be done (including waiting for a new JDK release/update) might
not be viable.
A decoupling of the skin and behaviors (for example by providing an additional
constructor that does accept the behavior) would further ease the process
of extending already existing controls.
If I might have misunderstood something about this JEP, or how
the control/skin/behavior works, please feel free to correct me.
More information about the openjfx-dev