Change existing controls or create new ones?

Philipp Dörfler phdoerfler at
Thu Mar 14 12:28:21 PDT 2013

Thanks for that detailed and quick response!

The reason for excluding transformations is a very valid one, indeed. Now that you mentioned the recommended solution I've found it in Group's javadoc and the one of Node's transform properties (e.g. rotate), too. Shame on me - that doc is very well written, actually. Might be worth pointing out at [1] (see the CSS of #button-custom) that Group would take care of the rotation bounds.

Regarding your advice on custom controls: That makes sense. One question remains, though: How well do assistive technologies for visually impaired deal with custom controls (or the standard ones)? Are there any resources on what API JavaFX provides for this? Only thing I've heard is that it implements the W3C API for RIAs [2], but that's more of a rumor. What about the Java Accessibility API?

~ Philipp


Am 14.03.2013 um 01:06 schrieb Jonathan Giles <jonathan.giles at>:

> Good questions. I'll do my best to answer them quickly now.
> Regarding the transformations and their lack of inclusion in layout: the reason for this is that more often than not a transformation is a temporary thing (for example a rotation / glow / drop shadow on mouse hover), and it is not desirable that the layout of your user interface be impacted by these transformations / effects (imagine a wide but short rotating rectangle node pushing / pulling all nodes around it as it goes through its 360 degree rotation).
> However, in saying this, if you do want your layout to be impacted by these transformations / effects the solution is simple: you wrap your Node in a Group, and place that Group in your scenegraph.
> To slightly deep dive (and I hope I'm right here - it's been a while since I've had to explain this), a Node has a few different layout bounds. The two most relevant to layout are 'layoutBounds' and 'boundsInParent'. The layoutBounds is actually what is used to determine sizes / positions of nodes in a layout, but this does not include transformations / effects. These impact the boundsInParent instead. The thing a Group does is gather together the boundsInParent of all of its children and make that its layoutBounds. This is why placing a Node with transformed boundsInParent will be used if you wrap it in a Group.
> Switching to custom controls / customised controls, in general the recommended advice depends on the requirements and availability of a suitable control to base customisations on. I would say the best general advice is to firstly try getting the look you want by just modifying CSS on a custom control. If this works then you're great and can stop. If this doesn't work then you could consider either extending or developing a custom Skin for the control, but this brings with it an expectation that you will support all API from the control class (which is often a big ask).
> One piece of advice I always give when I do conference sessions on custom controls is that you _do not_ have to build UI controls by doing it the way we do it in the UI controls team (that is by extending Control, SkinBase, etc). The only reason why you would do this is if you want to ensure maximum ease of distribution to third parties and the highest level of CSS skinning opportunities (but in saying that I don't think it is much greater than simply doing it the way I normally recommend, which is to extend Region and throw together your UI by adding children to the Region node).
> I hope that makes some degree of sense...
> -- Jonathan
> On 14/03/2013 12:35 p.m., Philipp Dörfler wrote:
>> Hi,
>> the question might benefit from a short example:
>> Some days ago I created a prototype of a TabPane [1] and then tried to achieve the same look by styling the already existing TabPane with CSS. The latter was not quite as successful, though [2] but I did not have the time to investigate much further. I know that it is possible to adjust the .tab-header-area's dimensions with CSS but as the dimensions of that header does not seem to obey the boundaries of the rotated tab, I would have to manage the tab-header-area's height (or width that is) manually.
>> The underlying problem here is that the JavaFX layout managers do in general not account for transforms, so scaling, rotations and translations result in the node crossing the container's boundaries.
>> I do not want to question whether this is "expected behavior" or not - I assume there are good reasons for the way it is implemented right now (and be it only the possibility of 3D transformations - and how should those be handled by container panes?).
>> No, my actual question is:
>> What is the preferred way to achieve a reusable TabPane which looks like [1]? Should one try to style the existing one using CSS and Skins or is it better to create a control like this from scratch? Just assuming the first were possible in this example (and it probably is), here are some quick pros and cons. I'd be happy if you could contribute some of your own:
>> Style existing controls:
>> - Better support for assistive technologies, screen readers (it's a TabPane, we already know how it works)
>> - => more semantical information
>> - already implemented functionality
>> Start from scratch:
>> - Greater flexibility in creating the visuals (wild guess - I have not bothered trying Skin myself, yet)
>> - no functionality implemented - you have to do every single thing yourself
>> - less semantical information (the screen reader or automation software does not know how a CustomFancyTabPane works)
>> Might someone who has a deeper understanding of controls shed some light on these questions, please?
>> Oh and - those reasons for not taking transformations into account... I'd be interested in them, too.
>> Cheers,
>> ~ Philipp
>> [1]
>> [2]

More information about the openjfx-dev mailing list