The trouble with Skins
krueger at lesspain.de
Mon Mar 23 18:45:09 UTC 2015
On Mon, Mar 23, 2015 at 7:07 PM, Richard Bair <richard.bair at oracle.com>
> tl;dr; I lean toward keeping the Control API as view-agnostic as possible,
> but where view details become essential to the operation of the control,
> then define the Control to always include those specific view details.
> Very interesting discussion, I’m enjoying reading through it. The
> following is a bit of background as to where my head was when we were
> designing this.
> In Swing we had a similar concept to the Skins, they were the various UI
> delegates. In theory they allowed you to change the look of a Swing
> component (and they did) — but there were all kinds of “view specific”
> details that leaked into it, and also in the Swing components. With JavaFX,
> I wanted to go down more of a purist route, where the Skin would literally
> do all the UI (view) and the control would be the controller. OK, the
> Control was a Node because it made more sense conceptually to put a Button
> into a scene graph than to create a Button, associate it with a view, put
> the View into the scene graph, and somewhere stash the controller so you
> could get it back later. And for something like a Button, it works well.
> Almost as soon as we’d gone down this road we got into the various
> problems you guys have been discussion around scroll bars and view
> positions. If you’re using the standard UI, then you kind of want to have
> access to these properties so you can get the UX right. However if we add
> these properties to ListView, then it would go down the road of saying
> “ListView displays a list of items and has a scroll bar or at least a
> scroll position and you have convenience API for making certain items
> visible, etc”.
> Another very common complaint was about how to go about knowing the size
> of a cell for a specific list view item. You’d really want an API on
> ListView that said “getCell(item)” and then you got the cell, at least
> assuming it was visible, otherwise since it is virtualized it doesn’t make
> a whole lot of sense. But anyway, if you don’t know whether the skin even
> does virtualization, then how can you define these semantics in a way that
> is broadly consistent and usable?
> Basically it comes down to having the API on the controller (Control) and
> restricting what kinds of skins can be created per control or having users
> cast the skin to a concrete type and work with the Skin directly for such
> things. If we were a dynamic language we could be dirty and munge the two
> together into a single thing (dynamic properties), but with its own set of
> trade-offs (you have to know what kind of skin you’re dealing with, and if
> you get it wrong, your app breaks).
> As time went on we ended up adding more view-specific functionality to the
> controls (even adding view state via the CSS background API etc!!). I don’t
> know what the right answer is for this design question, but where we were
> heading was a place where you would have different UI controls for
> different “classes” of controls. So a ListView with scrollbars is our
> ListView, and a PagingListView or something would probably be different.
> They could have a common base class if we designed it such, otherwise they
> would just have those similarities that are consistent between the two
> classes of control.
> That is why I find this actually quite appropriate:
> > So Skins prevent us from getting visual details of the Control (such
> > as scroll position, position of item on screen, ...), because it is
> > Skin-specific, but at the same time they fail to customize the look &
> > feel, because visual presentation leaks into the Control anyway.
> This is the design balance! If you get it wrong, you get exactly what
> you’re saying here.
> In the end, I lean toward keeping the Control API as view-agnostic as
> possible, but where view details become essential to the operation of the
> control, then define the Control to always include those specific view
Not understanding the discussion in-depth, I just hope that solving issues
like https://javafx-jira.kenai.com/browse/RT-39917 is possible within the
current design. If such limitations are something one has to live with, it
is not possible to create a UX that can compete with other toolkits
including Swing. At the moment this is a brick wall we seem to be hitting
porting our product from Swing to JFX.
More information about the openjfx-dev