JavaFX Abacus Tutorial, Part VI – Styling
This is the sixth part of a basic tutorial on JavaFX. The other parts can be found here and the code is on github. The running example of the tutorial is to build an abacus. If you are curious how the final solution will look like, please
have look at this 7 min video.
We have so far created the JavaFX abacus application without giving
any thoughts to the visual appeal of the app.
The good news is that JavaFX very nicely supports keeping functionality and
display aspects apart by means of CSS styling. We can simply apply style classes to
the various visual components and think about the actual visual properties later –
or even provide multiple styles that the user can choose from.
Styling comes in three steps:
- assign style classes to the components
- add a stylesheet to the scene
- fill the stylesheet
Adding a style class is easy. Each node has a getStyleClass() method that
returns an observable list of Strings, each of which is a name of a style class such
that we call
|
1 |
node.getStyleClass().add("mystyle"); |
BTW: the method name is a bit odd It should be named “getStyleClasses”.
The various builders make this even easier with the builder method styleClass(“mystyle”).
Second comes adding a CSS style sheet to the scene. Following the meanwhile
expected JavaFX pattern this is done via
|
1 |
scene.getStylesheets().add("/abacus.css"); |
The “/abacus.css” refers to a resource (file) that resides in the root of the classpath.
That makes it easy to package your styles together with the application in the same
jar file. There are more options for referring to styles like reading from external
sources or even to define styles right in the code, which is conventionally called
“inline styles”.
Last not least, we have to fill the CSS stylesheet, which is pretty much the same
experience like working with stylesheets for HTML. There are a few specialities
though when it comes to the availability of style classes, selectors, property names,
functions, and values.
The JavaFX CSS Reference Guide is an indispensible resource to get this work done.
Let us start with our black and white style:
First, we set an overall background for the “root” style class that JavaFX applies
to whatever happens to be the root node of your scene.
|
1 2 3 |
.root { -fx-background-color: papayawhip; } |
This gives us a nice sand-like background. The circles shall get two different
styles for easier counting: the ones on the left like bright, on the right like
darker wood. The shall also appear like balls, i.e. three-dimensional.
Making circles appear like balls either requires some elaborate
lighting-, shadow-, and reflection-effects or just a clever gradient. Let’s go for
the latter. Luckily, JavaFX gives us the radial gradient, which is perfect for
that purpose.
With the base color of “burlywood” for the darker balls and “papayawhip” for
a not too prominent highlight color, we place the highlight a little lower (16%)
than top-centered and let it shine on only the top half of the ball (radius 50%).
The ball should also be not 100% solid but slightly transparent with a
opacity of 80%.
Now comes the coolest trick: when you place balls close to each other like in
the abacus, then one ball’s highlight will slightly reflect on the ball in the
rail above.
As the painters say: “the shape is made from the light in the shadow”.
We achieve this effect by using the “reflect” property of the
radial gradient. This leaves us with the following style definitions:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.root { -fx-background-color: papayawhip; } .left { -fx-fill: radial-gradient(center 50% 16%, radius 50%, reflect, papayawhip, burlywood 80% ); } .right { -fx-fill: radial-gradient(center 50% 16%, radius 50%, reflect, papayawhip, sienna 80% ); } .rail { -fx-fill: linear-gradient(sienna, burlywood 25%, saddlebrown 50%) } .text { -fx-fill: white; } |
With this style, your abacus now looks like depicted below:
Not too shabby, I would say. But there is more.
Here comes another piece of painting knowledge: “every color also paints its
surrounding”.
We make use of that effect and change only one thing: the background – and we
change it into a radial gradient from red to black.
|
1 2 3 |
.root { -fx-background-color: radial-gradient(center 25% 25%, radius 60%, reflect, red, black ); } |
Doesn’t that instantly look like a casino’s red velvet furnishing and make the balls on their
rails appear like shiny pearls?
Personal tip: radial gradients in a rectangular frame often look spectacular.
I hope that by now you are convinced that styles are very helpful and that with only
minimal smart changes you can totally change the user experience of an application.
Homework
Come up with your own styles and don’t forget styling for the rails.
When a rail is selected – as to mark the baseline for calculations – it should
get a “selected” style class.
JavaFX CSS support the usual selector combinations such that you can specify the style
for the selected rail as “.rail.selected { … }”.
If you don’t want to see the digits, you can use the “transparent” color.
Next week with Dolphin
There still is an important piece of functionality missing: the automatic overflow.
Next week will address this issue with the help of a presentation model and business
logic that controls on it. We will use OpenDolphin to that end.
Finally
If you are committed to learn JavaFX,
please consider joining one of our JavaFX workshops at Canoo.
If you plan to migrate any current application to JavaFX,
please give us a call!
See you next week!
Dierk
P.S. the GroovyFX version by Tim Yates.
















