The past - Nifty 1.x XML based styles
Nifty 1.x used it’s own XML style format. With a custom syntax you’ve been able to apply attributes to Nifty controls based on the id of the element.
Here is an example of the old, Nifty 1.x way to style your GUI:
This worked but was a bit clumsy to handle at times, especially when you want to style more complicated controls that used sub-ids. In the end you usually had to copy the basic style and modify it. And in the worst case you kinda had to duplicate the hierachy of elements that your control consists of to modify its look and feel.
The future - Nifty 2.0 CSS
I’ve toyed with the idea of using CSS for quite a while now. And now it’s part of Nifty 2.0! Right now, it’s only the beginning - read: the only thing you can style is the background-color of a NiftyNode ;-) - but it’s easily (and I mean it, really easy) extendable for additional properties which we’ll do next. And later the same mechanism will be used to style controls as well!
Before we start to explore the details a little bit, I’d like to make sure what you can expect from Nifty 2.0 CSS - and what not.
First, it just takes the CSS mechanism and has nothing else to do with what you might know as HTML/CSS! So there will be no box model, there is no
display: float; and all of that. We’ll not try to emulate HTML with Nifty at all. And if you’re now a bit disappointed, read on! What we have in Nifty is not as bad as it sounds - actually it’s quite nifty …
So what we use is kinda a bare bones version of CSS consisting of:
- The CSS selector syntax to select Nifty nodes. Actually the full Selectors Level 3 spec is supported!
- The CSS rules will be applied to all matching Nifty nodes. We translate the rules to setters of the Nifty nodes automatically.
So here is a little example CSS that is already working:
So in the example we have the selector
.my which will select all Nifty nodes by the (new) cssClass attribute that you can set by code like so:
There are (a lot of!) other ways to write selectors and all of them are supported!
So once we have a Nifty node that matches the CSS class “my” the ruleset, in the example that is
background-color: #f00f; will be applied to the matching nodes.
Introduce CSS properties using @NiftyCssProperty
The steps necessary to introduce a CSS property to the NiftyNode Java class requires the following steps:
- There has to be a setter and a getter available for the property conforming to the JavaBeans spec, e.g. a simple method like
setStuff(). Nifty needs both, the getter AND the setter.
- Apply the @NiftyCssProperty annotation to the getter or the setter. Which one doesn’t matter. You can apply it to both methods too if you want but one would be sufficient.
- Provide the
nameof the property using the
@NiftyCssProperty(name = "css-name")syntax. This will be the name that is available in the CSS-file later.
- (optional) If your property is not a simple String property but an enum, a float or even a complex object, the
@NiftyCssPropertyallows to specify an implementation of the NiftyCssStringConverter.java interface. Using this interface you have a way to provide a conversion to and from the String stored in the CSS-File. (Here is an example implementation to convert NiftyColor: NiftyCssStringConverterNiftyColor.java)
And that’s it!
Adding a CSS stylable property with the @NiftyCssProperty is pretty straight-forward. Internally Nifty will use the CSS property, f.i.
background-color and the @NiftyCssProperty annotation to discover the actual getter and setter methods. When it later applies the CSS-rules it simply calls the setter for the property.
Libs used for CSS processing
Nifty utilizes two open source Java libraries to do the CSS parsing and processing.
First, there is Phil Browns jCSS-Parser which is a Stream parser for reading CSS files. It parses the CSS files and calls methods on a CSSHandler you provide. Very straight-forward to use and very nice!
The other project Nifty uses for processing the actual CSS-selectors is Christer Sandbergs css-selectors project. This project takes a selector and processes all of the details of the selector spec to queries into a DOM-tree (originally). I’ve generalized it and provided a pull-request to use the lib with general non DOM-tree based implementations like the one Nifty uses internally. At the time of this blog the pull request has yet to be applied to the project.
Using the two libs we can parse and process CSS very easily.
Currently, both libs have been added directly to the Nifty source tree because jCSS-Parser is not yet available in the Maven repository and the css-selector is available but not yet in the version we require. So for now we’ve took the brute force solution and included the source directly.
So, now you have it! CSS support in Nifty 2.0! Looking back at it, it was not really hard to add and I think we’ve found a nice solution that allows us to extend this further and use CSS to style GUIs in the future very easily!