Proposal to move default style-class from Control to SkinBase
David Grieve
david.grieve at oracle.com
Wed Aug 7 08:08:31 PDT 2013
Currently, a control has a default style-class. For example, you can use .button in a style-sheet to style a Button. I propose to move the default style-class from the control to the skin (RT-32186). The impetus for this change is two-fold.
Firstly, it can be argued that setting the style-class of a control should be left to the developer, that imposing a default style-class is implementation detail leaking into the public API. Moving the default style-class from the control to the skin addresses this concern.
The second motive has to do with CSS processing itself. When a skin is set on a control, the control adopts the styles of the skin and css is reapplied to the control in order to pick up the new styles. Thus, it takes two CSS passes to fully style a control. By moving the default style-class to the skin, the control no longer has to adopt the skin's styles. Styles still have to be applied to the skin, but this can be done from the skinProperty's invalidated method. These subtle changes - not adopting the styles and applying css to the skin from skinProperty's invalidated method - will simplify the code in Control.
The reason for moving the default from Control to SkinBase and not Skin is that there is no API in Skin for getting style-class (or any other css selector attributes). Skin could implement the Styleable interface, but that would not be backward compatible.
Another issue related to CSS processing has to do with looking up cached, matching styles for a node. When the skin is set on the node and adopts the styles of the skin, css is reapplied. This means that the css implementation will look for matching styles for the control. There is a map that has a node's simple class name, style-class, and id (the 'css selector' aspects of a node) as a key and the matching styles as a value. Since none of the 'css selector' aspects of the node have changed, the previously cached value is returned from the map. Then when the styles are applied to the node, css says 'oh, I've already calculated values for this kind of node' and doesn't bother looking up the properties that were added by the skin. This causes problems such as https://javafx-jira.kenai.com/browse/RT-31691.
The cache lookup issue can be resolved in other ways, such as adding the list of properties to the key, or adding a flag to cause css to calculate a value if there is no previously calculated value found. But I believe that moving the default style-class will lead to cleaner code.
If a control no longer adopts the skin's styles, then the control and the skin could be styled as separate entities. This would mean that instead of
.tool-bar { -fx-orientation: vertical; -fx-spacing: 3; }
one would have to write
ToolBar { -fx-orientation: vertical; } .tool-bar: { -fx-spacing: 3; }
since orientation is a property of ToolBar and spacing a property of ToolBarSkin. This is an issue for maintaining backward compatibility with existing stylesheets. This isn't a issue for caspian or modena but is for author style-sheets and inline styles. I have some ideas here, but all of them rather clunky and kludgey. My question on this point is whether or not this is a real concern.
More information about the openjfx-dev
mailing list