Subclassing behavior in JavaFX Controls
Pete Moss
peatmoss84 at gmail.com
Wed Sep 17 19:35:49 UTC 2014
Tomas,
Thanks for the fast reply.
I read your blog post that you referenced and I agree with you 100%. I am a
crusty MVC person and I agree, that having the Skin class (View) hold a
reference to the Behavior class (Controller) rubs me the wrong way from an
MVC perspective.
I was looking at the JavaFX source code and trying to figure out the
easiest source code path to a fix. But I agree with you that a slight
redesign would be better to bring it closer to a purer MVC approach (to
loosely quote General Jack D. Ripper, we must strive for a Purity Of
Essence). ;)
Doing what you propose would provide a much greater degree of flexibility
to subclass the skin, behavior or both.
I read the back and forth between you and Jonathan Giles on your blog post,
and although I agree with you that a refactoring and restructuring would be
better, I understand Jonathan's point of view, given that the horse is out
of the barn with the current APIs and what you are proposing is a little
more invasive.
Which brings me back to my post and my desires to subclass skin, behavior
or both for existing JavaFX Controls. It seems impossible to subclass skin
and behavior. Replace, yes, but not subclass (augment).
Again, any suggestions for workarounds would be appreciated.
On Wed, Sep 17, 2014 at 3:02 PM, Tomas Mikula <tomas.mikula at gmail.com>
wrote:
> 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