JavaFX: Building custom controls

One of the big criticisms leveled at JavaFX presently is its lack of controls (or components if you come from the Swing world). This was addressed to some degree in JavaFX 1.2, but there are still many controls missing, and some of the controls in the latest release have relatively basic API’s at this point. Certainly this will improve in future releases, but I thought I’d try to simply explain the process you need to go through to build your own controls. Who knows, you might be able to sell them if you get them good enough.

In JavaFX, there are three classes that you should become familiar with: Control, Skin and Behavior. Simply put, the Control class should be used to maintain state. It can have it’s look (but not feel) modified by assigning a different Skin instance to the skin variable. To separate the look of the control from how a user interacts with it, you should put all user interaction code into a Behavior instance, and assign it to the behavior variable within Skin.

I’ll jump right into a demo now. The demo is of a button (this term is used very, very loosely as I wanted to keep the code simple), and is split between three classes, as well as a test script to use the new button control. I have neglected to include any package and import statements, just to keep the code concise.

Firstly, the control itself simply has a text variable to store the buttons text. It also creates and sets an instance of the new skin, which handles the painting.

Secondly, we have the skin class shown below. It is necessary to implement the contains and intersects methods, but you can normally just reuse the code I have below for that. Note that I can access the control variable directly, but I cast it to be an instance of JGButton so I can access the text variable. Note also that I override the behavior variable to use my own implementation. Finally, you should note that I create a Group of nodes to represent my button, and I assign this to the node variable. I attach a few mouse listener functions to this node, allowing me to palm off the functionality to the behavior class. This allows me to change the skin without worrying about the behavior code needing to be needlessly duplicated to all skins.

Thirdly, we have the simple behavior class, which is where I have put in functions related to the buttons behavior. Oddly, the Behavior class offered by JavaFX only currently supports keyboard input, so it is necessary to write mouse input events from scratch. I’m not sure why this is, but perhaps Richard might leave a comment related to this. The only thing to note in this class is that I can access the skin and control through the skin and skin.control variables respectively.

Finally, we have a very simple test script, with nothing really worth noting. When the application starts, we have a red ‘button’ with the text “Button Text” printed atop it. When the mouse clicks on it, “Button pressed” is printed to the console. When the mouse moves over it, the text of the button changes to “Button entered”, and when it moves away from the button, the text changes to “Button exited”. Yes, it’s a very useful button.

I hope this quick and simple tutorial on creating custom controls in JavaFX has been useful. I tried to keep everything as simple as possible, but if you have any more detailed questions, please leave a comment or email me. Cheers!

JavaFX Node Bounds: I don’t get it

I’m happy to admit it when I don’t get something. The situation with boundsInLocal, layoutBounds, and boundsInParent in JavaFX is one of these situations. I have read a number of articles discussing this topic, and whilst I understand the differences between the three values technically, I don’t think I’ve seen an article that tells me why I need all three values, and when I should choose one over the other.

So, please, can someone out there write a blog post and/or add a comment to this post to explain to me, and to others, why I need to care about these three different values. If you do write a separate blog post, please leave a comment here so that anyone who stumbles upon this blog post in 6 months time can follow through to any other discussions elsewhere.

Most importantly, keep it simple. I know, that’s more difficult than being complex and detailed, but for the sake of JavaFX clarity the world over, please keep it simple. We want to know, simply, why and when do I care about the three different values?

Thanks in advance!

Java desktop links of the week, June 29

To everyone reading and commenting on my blog – thanks – you help make the world go round 🙂 Here we go again.





  • Andres Almiray posted two updates on FxBuilder for Groovy.

Have a great week everyone, and for those of you in the northern hemisphere, enjoy the nice weather – it’s freezing and dark here in New Zealand!

JavaFX: Bound functions

Binding in JavaFX is of course very cool, and in most circumstances it makes sense. I thought I would make a quick post to explain what a bound function is, and how you should go about interpreting code that uses this language feature. I want to make this post as simple as possible, so as to not overcomplicate things. Before I begin I must thank the Pro JavaFX Platform book guys – I base this explanation on code from their (highly recommended) book.

A bound function looks like this:

The interesting thing about this function declaration is the bound keyword. Looking at the body of the function, we note that the function makes use of variables y and z from the function, and assigns these to variables u and v respectively. In actual fact, the z argument is never used, but an x value is used. This x value is declared outside the function, and is therefore available to be used by it.

This function can be used as per usual in our code simply by calling f(1,2), for example. The feature that is offered by the bound modifier is that we can bind to the function, and when the x or y variables values change, the function will re-evaluate itself. An example is shown in the code below:

On line 3, c is bound to equal the result of calling the function f(a, b), which will result in c being set to equal 7.0 (as a=4,b=5, and x=3, and f is the sum of a and x).

Line four changes the value of x from 3 to 5. Because the f function is a bound function, and the c variable is bound to the f function, we re-evaluate f(a, b), and assign the new value of a+x to c, which means that c is now equal to 9.0.

Similarly, when the a variable is changed on line 5, the function is re-evaluated, as it has determined that the value of a is relevant to the value stored in c.

As noted previously, the value of b is not used in the function, and therefore when it changes it does not impact on the value of the variable stored in c. Because of this, when the value of b is changed on line 6, c is not re-evaluated, as JavaFX is smart enough to know that this does not matter.

If the c variable was declared as f(a, b) (i.e. it is not bind f(a, b)), then when x is updated, c will not be recalculated. Similarly, if the function declaration for f is not declared to be bound, c will not be updated either. However, both of these permutations are legal syntax – it just results in different outcomes. To have f re-evaluate itself and the value be assigned to c, it is necessary the both the function be declared bound, and the assignment to variable c be bound (using the bind keyword).

I hope that makes sense, and clarifies the purpose of the bound keyword.

JavaFX: Thick TextBox Borders

Being the UI geek that I am, I wanted to look at borders in JavaFX, as I had noticed that there seemed to be some inconsistencies. It turns out that I shouldn’t have been too worried – it appears that only one control looks bad, and it is the TextBox control. Shown below is a screenshot of a demo application I wrote, which has a number of controls placed in it.


Note that the borders of all controls look pretty similar – a single pixel width and all a dark grey. Swing suffered from border abuse and inconsistent border colours, so I am happy to see JavaFX is much better.

As mentioned, the only exception is the TextBox, which in the screenshot says ‘Original’. I think it’s probably agreeable to most people that this control has a border which is too thick (and a font which is not consistent with the font used in other controls). To fix the border inconsistency is actually quite simple, as shown in the TextBox directly beneath the original which shows ‘Fixed’. I think it’s probably agreeable that this fits it better with the other controls.

Finally, beneath the ‘Fixed’ TextBox is the text ‘Invisible’, which is actually also a TextBox with no border being shown. I include this for a reason, which will become clear soon.

Anyway, on to the fix – it’s simply a matter of changing the style by adding a line of CSS. The code for the three text boxes is shown below, in the same order as shown in the screenshot.

In otherwords, to fix the border problem, you need to set the border-width to 0, which doesn’t seem correct – you’d expect a control with a border-width of 0 to have an invisible border. In fact, to get an invisible border is shown in the last TextBox – you have to set border-width to be -1.

So, perhaps this is a bug, or perhaps it’s a design choice. I thought I would document it here so that people searching Google for answers might discover it without having to do trial and error. Perhaps this might be fixed in a future JavaFX release.

Additionally, the TextBox font also seems to be inconsistent, but I won’t bother to discuss this as I would hope anyone reviewing this post will also realise they need to fix the font. Perhaps this may be fixed in a future JavaFX release too.