Subclassing behavior in JavaFX Controls
Pete Moss
peatmoss84 at gmail.com
Wed Sep 17 18:36:48 UTC 2014
I am starting to work with the TableView JavaFX Control. I see that it has
some nominal keyboard handling, but it is incomplete for my needs. From
what I understand about the JavaFX Control architecture, all of the JavaFX
Control-derived classes use a Skin class created via
Control.createDefaultSkin() which, in turn, contains a behavior class that
is derived from BehaviorSkinBase.
However, an Oracle publication says that Control developers should NOT use
BehaviorSkinBase since that is a private API.
So here is the problem. I am trying to augment the behavior of the
TableView class. The keyboard handling is done in TableViewBehavior so it
would be nice for me to supply a subclassed version of TableViewBehavior to
augment that behavior or override some of it. But I can't. If you look at
the TableViewSkin class, here is the ctor that gets used:
public TableViewSkin(final TableView<T> tableView) {
super(tableView, new TableViewBehavior<T>(tableView));
...
}
Because this is the only ctor available for TableViewSkin, I don't see any
way I can subclass TableViewSkin and supply my own behavior instance. I
can, of course, create my own skin, but then I would lose the code in
TableViewSkin (unless I shamelessly copied it, which I don't want to do).
It seems to me there could be a couple of different ways to fix this:
1) Add an alternative ctor that takes a behavior instance as a second
argument. Then refactor the original ctor to call this, eg,
public TableViewSkin(final TableView<T> tableView, BehaviorSkinBase
behavior) {
super(tableView, behavior);
...
}
public TableViewSkin(final TableView<T> tableView) {
this(tableView, new TableViewBehavior<T>(tableView));
}
2) Add a factory method for the behavior instance:
public TableViewSkin(final TableView<T> tableView) {
BehaviorSkinBase behavior = behaviorFactory(tableView);
super(tableView, behavior);
...
}
protected BehaviorSkinBase behaviorFactory(TableView<T> tableView)
{
return new TableViewBehavior<T>(tableView);
}
I see this as a shortcoming in the JavaFX architecture. If I were building
a custom Control, it would not be so bad since I would provide an
additional Skin ctor that takes a behavior class as an arg, but it seems
that the way the code is currently structured, it is difficult to subclass
a JavaFX Control and subclass its skin and behavior too.
Any thoughts on how to workaround/solve this would be greatly appreciated.
More information about the openjfx-dev
mailing list