Home >
A while back, in the previous part of this bluffer's guide, we looked at JavaFX Script's declarative syntax, and support for sophisticated binding of code to data. In this part we're focusing entirely on strings.
Not the most exciting of topics, you might perhaps be thinking? Well, perhaps you'll change your mind by the time you reach the conclusion.
An application's user interface does two things: it accepts input from the user, and it reflects the application's current state back to the user. Even in this modern multimedia age a huge part of human/machine communication still largely depends upon ancient glyph based encoding systems, known more commonly to you and me as written text. Even in the Star Trek age of direct voice interaction, the richness and scannability of written language will likely still be king for many types of communication. Writing may be almost as old as the hills, but it shows no sign of vanishing any time soon.
In programming, the humble character array, aka the string, typically represents written text, and it serves its purpose well -- so long as messages are largely static. When messages contain dynamic elements, however, the process of stitching all the bits together can become cumbersome. Given the abundance of dynamic text in modern software, it's a wonder nobody has thought to add more sophisticated string manipulation into programming languages.
Until now, that is. Because JavaFX Script's mission to create a better client side programming language has meant some interesting additions to the ways strings can be created and manipulated. And it's these additions we'll be looking at below.
Is that an expression in your string, or are you just pleased to see me?
Let's kick off with a basic example:
var username:String = "joe";
var domain:String = "example.com";
println("Email: {username}@{domain}");
Output:
Email: joe@example.com
The JavaFX Script code above needs little explanation. username and domain are string variables, and the println() call prints them, combined to form an email address. You can immediately see how JavaFX Script favours the simple referencing of a variable within a string (wrapped in braces) over cumbersome concatenation operations, or printf style token replacement.
The next fragment of code follows on where the last left off:
def email:String = bind "{username}@{domain}";
username="jane";
domain="test.com";
println("Email: {email}");
Output:
Email: jane@test.com
In part one of the bluffers guide we saw the magical bind keyword, which creates an auto-update relationship between a variable's content and the data it depends upon. In the above code the email variable is bound to username and domain; when either changes (as they do in the next couple of lines) email will update itself.
var online:Boolean = false;
def status:String = bind
"{username} is "
"{if(online) 'online' else 'offline'}";
println("Status: {status}");
online = true;
println("Status: {status}");
Output:
Status: jane is offline
Status: jane is online
I have a confession to make. A few paragraphs back, when I explained how variable references can be embedded directly inside a JFX string, I lied (just a little!) That stuff inside the braces isn't just a variable reference, it's a piece of code -- we can use any code expression inside the braces so long as it returns a string (this includes calling functions!) In the example above we use a simple if/else block (highlighted in blue) to translate a boolean into an appropriate piece of text. Because the status variable is bound, the string will auto-update whenever username or online changes.
Going global
Embedded expressions mean we can create dynamic text strings which rely on complex pieces of code. Obviously we could use embedded expressions to format the way the string's variables appear, although this is such a common operation that JavaFX Script has as special bit of syntax for it. In the code below you'll see how it permits the inclusion of a formatting block inside the braces:
def magic = -889275714;
println("{magic} in hex is {%08x magic}");
def now:java.util.Date = new java.util.Date();
println("Today is a {%tA now}");
Output:
-889275714 in hex is cafebabe
Today is a Sunday
The format syntax will be familiar to anyone who has used Java's java.util.Formatter class. In the example code the integer is shown as hexadecimal, and the date becomes just a day of the week. Java's Formatter has quite a wide range of formats for common data types, but the cute thing about JFX's embedded expressions is we always have the opt-out of calling a function if we need something unusual.
Perhaps the biggest cause of change to an application's text is localisation. Different counties have different languages -- indeed even between counties sharing the same language (for example the USA and UK) there can be stark variations in vocabulary and grammar. To be truly international an application needs to adapt its text to meet the needs of the local environment. Here again JavaFX Script helps us out.
For each class in our application we can create one or more companion property files, with alternative text appropriate to a given locale, like so:
File: MyClass_en_UK.fxproperties
"Trashcan" = "Rubbish bin"
"SOCCER" = "Football"
The file above will provide alternative definitions for UK English (as opposed to US English). Bundling this file as a resource within our application, with its very specific filename, is all that's required for JavaFX to automatically find and use it.
def str1:String = ##"Trashcan";
def str2:String = ##[SOCCER]"Soccer";
println("{str1}, {str2}");
Output:
US: Trashcan, Soccer
UK: Rubbish bin, Football
A double hash prefix tells JavaFX Script to attempt to localise the string, using a properties file like the one previously seen. We can either use the string contents itself as the lookup key (as is the case with Trashcan), or we can specify a separate key (as has been done with SOCCER). If JavaFX can find a suitable properties file for the locale the code is running in, and it contains the appropriate key, the string contents are swapped for the localised version.
Conclusion
And that's it for part two, I hope you found this little excursion into JavaFX strings informative. Given the amount of text most software has to deal with, it's surprising just how primitive string manipulation is in popular programming languages. One of the goals of JavaFX is to reduce the levels of ugly and time-consuming boilerplate code in UI programming, and its string handling certainly takes a huge step in that direction.
It only remains for me to remind you about JavaFX in Action if you want to read more (available at all good bookstores, and probably a few bad ones too!) The book covers JavaFX from a practical perspective, explaining not just how but why, making it a good companion to the official on-line documentation.
Until next time...




Facebook Application Development
Comments
Leave a comment