Subclassing behavior in JavaFX Controls
Tomas Mikula
tomas.mikula at gmail.com
Wed Sep 17 19:02:35 UTC 2014
Hi Pete,
work on this is tracked in https://javafx-jira.kenai.com/browse/RT-21598
In terms of the current API, I think the best solution is to add event
handlers and/or event filters on the TableView.
Regarding your proposed fixes, I have a blog post where I argue that
the wiring between the Behavior and the ("View" aspect of the) Skin
should be reversed, i.e. that the Behavior should hold a reference to
the View, not vice versa. That is, for example, against both your
proposed fixes. (Note that the blog post represents my personal view
only.) http://tomasmikula.github.io/blog/2014/06/11/separation-of-view-and-controller-in-javafx-controls.html
Incidendally, I'm currently working on a solution to add/override
keyboard shortcuts. I should be able to publish something soon.
Best,
Tomas
On Wed, Sep 17, 2014 at 8:36 PM, Pete Moss <peatmoss84 at gmail.com> wrote:
> 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