Monday Nov 18, 2013

MonologFX Update: Timed JavaFX Dialogs

When I wrote the original MonologFX dialogs for JavaFX, I was just trying to clean up a few things I'd done in my earlier project, DialogFX, that I felt could have been done better. Based upon some excellent feedback and suggestions, I rolled out the update...just as the OpenJFX team was releasing their own dialog code that is destined to be in JavaFX/OpenJFX. :-) As I mentioned in this previous post, rather than just hoard the code, I released it anyway in the hopes others might continue to find it useful - and updated the dialogs in the JFXtras Labs library as well - but didn't really expect there to be much continued interest.

I'm happy to say I was wrong. One of my goals was to make a very simple set of dialogs that worked well in most cases and that just "got out of the developer's way" you didn't have to think about extensively to use in your JavaFX application, just "drop & go". They were never meant to be all things to all people, rather a solid option for most use cases. But...

I've gotten some excellent follow-on requests, and I've explored several of them. While I may never have the time to implement them all - and some wander FAR from the original goals - some just fit. One of those ideas was for timed dialogs.

What is a Timed Dialog, and When Would I Use It?

A few developers pointed out that there are occasions when an app is running unattended and dialogs can either a) stop everything or b) pile up by the droves on the user's desktop. And JFXtras implementer Scott mentioned how nice it would be to have an informational dialog that worked similar to a mail notification, popping up and then disappearing after some pre-determined amount of time. The user should also be able to clear the dialog immediately, of course.

Enter the timed dialog. Drawing inspiration from the aforementioned mail notifications and a sample game by colleague Angela Caicedo, I expanded upon Angela's game-switching example to create a (hopefully pleasing) dialog fade in/out effect. Using the number of seconds specified by the developer (you!) via the method setDisplayTime(int displayTime), MonologFX apportions a reasonable percentage of that time to fade in, display, and fade out operations...making user input entirely optional.

What Does it Look Like?

It's much easier to demo than it is to explain, so I created a quick video of a normal dialog, then a timed one, in action. Click here to watch it on YouTube.

Limitations, Caveats, "Keep Off the Grass" Signs

A timed dialog is really best suited for informational dialogs - those where there is no user input required, like the aforementioned mail notifications. If a response is required from a user and a dialog disappears of its own volition, which option should be chosen? The "cancel" option would seem best in some cases, and the "default" in others.

Creating the fade in/out effect required a non-blocking implementation, which meant that it would always return a value immediately...and in the current design, that is "cancel". Which again points to using them as informational dialogs, but not for obtaining user feedback.

So for the foreseeable future, timed dialogs are really focused upon and should be confined to use as informational dialogs. If you need the application user to make a conscious choice prior to proceeding, keep that dialog prominently displayed until you get a response!

Where Can I Get Them?

I've already pushed the code to my Github repository for MonologFX and the JFXtras-Labs 2.2 and JFXtras-Labs 8.0 repos. And if you just want to download a .jar file and kick the tires, I've put a copy in the MonologFX repo's dist folder. Just download the .zip file, unzip it, and run java -jar MonologFX.jar for a quick demo.

Odds & Ends

I also made a few architectural changes to MonologFX this weekend during our first-ever "Thanks For Sharing Informal, International HackFest", and more will be integrated over time. Please stay tuned for more information. :-)

Happy Coding!

Friday Aug 30, 2013

Join me at JavaOne 2013

I'm excited to be able to speak at JavaOne again this year! Last year was an incredible experience, great brain food for anyone committed to Java and the Java ecosystem. This year promises to be even better.

This year, I have the privilege of sharing the podium with some of my favorite folks in the world, from around the world! Here are the sessions I'll be taking part in:

Session ID: BOF2605
Session Title: JavaFX, Widgets, and Apps, Oh My! Launching Frameworks for Platforms Large and Small
Venue / Room: Hilton - Plaza A
Date and Time:9/24/13, 18:30 - 19:15

This is a Birds Of a Feather (BOF) session by Hendrik Ebbers, Carl Dea, and me. The best thing about BOFs (for me) is that in addition to allowing us to share what we've been working on, it allows like-minded attendees to fully participate, asking questions, sharing ideas...more like a round table for the whole room to take part in. It's incredibly stimulating, and a lot of learning takes place for all involved.

Session ID: TUT3676
Session Title: Java Embedded Extreme Mashups: Building Self-Powering Sensor Nets for the Internet of Things
Venue / Room: Hotel Nikko - Nikko Ballroom I
Date and Time:9/24/13, 12:30 - 14:30

This is a two-hour tutorial where Jose Pereda and I take attendees through building a self-licking, renewable energy (RE) ice cream cone.  :-)  Renewable energy systems come in all shapes and sizes, and embedded systems - especially Java-driven ones - are excellent for monitoring those systems. Building remote sensor nets that not only monitor and report system status, but are also powered by those same RE systems, is inexpensive and straightforward once you have the right hardware and know-how. We cover everything from hardware to software, communication and optimization, with solutions that scale well from small personal systems to utility-sized deployments. And we have a good time doing it.  :-)

So please, come join us! There's no better place to see what's happening in the world of Java than JavaOne. Hope to see you there!

All the best,

Tuesday May 28, 2013

Virtual Developer Day: Java ME, SE, and EE

It's an exciting time in the Java Jungle! There are a lot of things going on "in Java" right now, and as a result, there are several free webinars scheduled to provide introductions to technologies and concepts you might want to know a bit more about. Just recently, I mentioned the upcoming Introducing Java EE 7 webcast, and now there's another one you'll probably be very interested to attend. The best part(s)? You can attend from your home or workplace and it's completely free! The worst part? You may struggle to decide which track to take - they're all that good.

For this four-hour Virtual Developer Day, here are the tracks and their topics:

Separate dates/times are offered for western and eastern hemispheres; please click this link to learn more and register.

Keep the Java flowing,

Wednesday May 22, 2013

Java EE 7: Get Ready!

With the recent approval of the Java EE 7 platform JSR, Java EE 7 is on its way!

There will be two webinars to introduce new features and give you an idea of what all the buzz is about. You can access this feature-packed event from your own desk, jump in when you can and step away when you need to do so. Registering once gets you access to both days, so you can sign up now and nail down your schedule as the time approaches.

What will you see in this online event ?
  • Business Keynote (Hasan Rizvi and Cameron Purdy)
  • Technical Keynote (Linda DeMichiel)
  • Breakout Sessions on different JSRs by specification leads
  • Live Chat
  • Lots of Demos
  • Community, Partner, and Customer video testimonials

Follow this link to sign up, or click on the images above/below. "See" you there!

All the best,

Tuesday Feb 26, 2013

How to "Pretty Up" Your JavaFX TableViews

One day you're a happy JavaFX developer, cranking out applications and blissfully providing your application's users with table after table of rich textual information. The next day it happens: your users approach you and ask if there's a way to include a thumbnail of each part in the inventory list. Or a small photo in the contact list/personnel roster. Or a snapshot/graph of the latest conditions for each monitored sensor or weather camera. So now what?

PropertyValueFactory, a convenience implementation of the Callback interface, is typically used to handle the work involved with populating all cells within a single TableColumn. As long as you provide the name of a valid property to the PropertyValueFactory constructor and set the TableColumn's CellValueFactory to the resulting PropertyValueFactory, the cell is populated, TableView adds an observer to the value, and life moves merrily along.

Adding a graphical element to a TableView isn't much harder, actually. The TableColumn's CellFactory handles rendering of the cell's contents, so if you want to place something other than textual content in the cell, you'll need to also set the TableColumn's CellFactory to one of your liking and override the updateItem() method. Let's take a look at a quick example.

I'd always intended to create some small-but-useful Twitter utilities and hadn't really had the opportunity, but a simple Twitter client provides a perfect demonstration of this capability. Here is an example of what a "feed" interface might look like:

For this TableView example, there are only two columns:

  • one for the user, showing the user's picture, name, and screen name
  • one for the tweet

The tweet's text is simply a string property of each MTweet object, but the user information comes from several properties of the MTweet object's associated MUser object. The MTweet's text is properly assigned to the cell's text property per the discussion above, but what about the user information? Per the JavaFX 2.2 docs,

Because by far the most common use case for cells is to show text to a user, this use case is specially optimized for within Cell. This is done by Cell extending from Labeled. This means that subclasses of Cell need only set the text property, rather than create a separate Label and set that within the Cell. However, for situations where something more than just plain text is called for, it is possible to place any Node in the Cell graphic property. Despite the term, a graphic can be any Node, and will be fully interactive. For example, a ListCell might be configured with a Button as its graphic. The Button text could then be bound to the cells item property. In this way, whenever the item in the Cell changes, the Button text is automatically updated.

To display the tweet's text in the "Text" column of our table, a couple lines of code does all that is necessary:

In order to bundle the user information and place it within a single cell, we set the "User Info" column's CellValueFactory in similar fashion to our text column above:

And then we set that column's CellFactory to something along the order of this:

For each cell in that TableColumn, updateItem is called with that cell's contents as the "item", the first parameter. Within our example above, we create a VBox, populate it with the user's photo (Image, via ImageView), name (String) and screen name (String), do a bit of formatting, and assign the VBox to the cell's graphic property. And with that, we're off and running. :-)

There is much more you can do, and this should get the ideas flowing. Here's to prettier apps (better optics?) and happier users!

All the best,

<<< UPDATE 1 >>>

Jonathan Giles, JavaFX team UI Controls tech lead, made a few suggestions for improving the efficiency of the code used above. The points he made were excellent, and I wanted to provide an update that shows revised code that incorporates them. I did leave the original code above, as I'm hoping it helps make a clearer path for those implementing similar code for the first time.

In order to override the TableCell constructor, we'll extend the particular TableCell<MTweet, MUser> class. Doing so allows us to create the VBox, Labels, and ImageView used in our composite user cell once per cell, rather than each time updateItem() is called. While we're at it, we'll also perform formatting/assignment duties in the constructor and avoid repeating those calls. Here is the new derivative class:

Creating the new UserTableCell class means we can update our setCellFactory() method call for our user info column like so:

Thanks to Jonathan Giles (@JonathanGiles) for the suggestions!

All the best,

<<< UPDATE 2 >>>

One more update! This time using an anonymous inner class for the column's cell factory. Same basic functionality, but this is perhaps the tidiest option.

Options are good, as they say...  :-)

All the best,


The Java Jungle addresses topics from mobile to enterprise Java, tech news to techniques, and anything even remotely related. The goal is to help us all do our work better with Java, however we use it.

Your Java Jungle guide is Mark Heckler, an Oracle Senior Java/Middleware/Core Engineer with development experience in numerous environments. Mark's current work pursuits and passions all revolve around Java and leave little time to blog or tweet - but somehow, he finds time to do both anyway.

Mark lives with his very understanding wife & kids in the St. Louis, MO area.

Stay Connected


« March 2015