Subclassing behavior in JavaFX Controls

Tomas Mikula tomas.mikula at
Wed Sep 17 19:02:35 UTC 2014

Hi Pete,

work on this is tracked in

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

Incidendally, I'm currently working on a solution to add/override
keyboard shortcuts. I should be able to publish something soon.


On Wed, Sep 17, 2014 at 8:36 PM, Pete Moss <peatmoss84 at> 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