<< Ubuntu diskspace on / | Home | Tapestry 5 and GWT - part 2.5 >>

JavaFX, WidgetFX and my first widget

A few tips & tricks, a little DiskSpace Widget

I became interested in the early version of the JavaFX Script language, F3 script, thanks to the nice GUI and graphics demos. I'm guessing I'm not alone in that :)

Anyway, the preview release of the JavaFX SDK was released a while ago and I looked at it with some interest. I became more interested in actually doing something with it when I saw the WidgetFX project, simply becuase I like the idea of widgets/gadgets etc. Until now I haven't been able to develop and run them in a Java environment. I also saw the oppertunity to actually learn JavaFX Script since widgets are a really good way to make a really small, but still useful application, while getting to know the language.

If you're interested in developing widgets you really should check out the WidgetFX Developers Google group. People like Stephen Chin, who's been answering loads of my questions :), are really good at answering all kinds of questions about WidgetFX!

It took me quite a lot of time to get at least a bit used to declarative UIs. I'm still not there, but I've made some progress and it's fun.

This is just a small post about my first widget, a disk space monitor. It's not a step by step tutorial, more of a tips and tricks for a beginner. I've included stuff I've learned when working with the JavaFX Script language and the WidgetFX API. It'll require at least some basic knowledge of the JavaFX script language.

Read on, visit the quite sparse DiskSpace Widget page or try it out right now.

Versions used:

DiskSpace Widget

The DiskSpace widget is nothing complicated, it's just a small widget displaying how much free space there is on a device. You can try it out here: DiskSpace Widget Remember that it's supposed to run in the WidgetFX container so it's not supposed to be a standalone Java Web Start application.
Update: How clumsy of me to forget to add index.html to the welcome files list. Done. Now the link should work. Thanks to Stephen Chin for pointing that out.

The icon I'm currently using in the widget is from the really nice collection Tango Desktop Project. Check it out if you need good looking icons in either PNG or SVG format.

Progress bar

The first thing I started out with was the progress bar. I didn't really know where to start so I simply looked at James Weaver's GUI demo and copied what I needed from that. I really love it when people are helpful and shares these kinds of things. Big thanks to James Weaver for some really good looking demos and their code!

WidgetFX Configuration

Configuration is a handy feature of WidgetFX. It's simply automaticly persist a basic object like Strings, Numbers, Booleans etc. for you. All that is needed to persist for example a String is this:
Configuration
    configuration: Configuration {
      properties: [
        StringProperty {
          name: "path"
          value: bind path with inverse
        }
      ]
    }
    
However you'll need to supply your own GUI for each configuration property. Here's a piece of code from my widget. This handles the disk space path. I've not gone through it really well since I'll have a few things I want to get done before I add all the config I need, so if you see something strange shoot me a message.

I have two variables here, the path and configPath. That's because bind path with inverse instead of using configPath would keep the TextField and the path in sync all the time and I don't want the change to happen before the user clicks the Done button.
Configuration with GUI
        var configPanel:ClusterPanel;
        var path:String = System.getProperty("user.home");
        var configPath = path;

        private function updatePath() {
            file = new File(path);
        }

        private function initConfig() {
            configPanel = ClusterPanel {
                var label = Label {text: "Path:"};
                var textField = TextField {
                    text: bind configPath with inverse,
                    hpref: 300 };
                vcluster: ParallelCluster { content: [
                    label,
                    textField
                ] }
                hcluster: SequentialCluster { content: [
                    label,
                    textField
                ] }
            }
        }

        private function configSaved():Void {
            path = configPath;
            updatePath();
        }

        Widget {
            configuration: Configuration {
              properties: [
                StringProperty {
                  name: "path"
                  value: bind path with inverse
                }
              ]
              component: bind configPanel;
              onSave: configSaved;
        }

        onStart: function():Void {
            initConfig();
        }
    

Preview code

Widgets can't be previed in the SDK preview panel since they are not based on a class the preview can render, like for example Frame. However having a preview can still be useful. Having a little piece of "preview code" in your custom node can achieve this with little work.
Widget with preview code
        import org.widgetfx.Widget;

        // Main widget code
        Widget {
            content: [
                Group {
                    content: [
                        ProgressNode {
                            progress: ...
                            progressTitle: ...
                            margin: 4
                        }
                    ]
                }
            ]
        }

        // Preview code
        import javafx.application.*;
        Frame {
            visible: true, width: 200, height: 200;
            stage: Stage { content: [ ProgressNode { progress: 0.7, margin: 4, progressTitle: "test" } ] }
        }
    

JavaFX Script

As I stated in the beginning of this post, widgets are a really good way to get to know this language. There are a few things

Sensible defaults

Always include sensible defaults when you create your own CustomNode. It's so much easier to try out things you don't know if there is a set of default values that presents something in a nice way.

Timeline

Even though it's in the animation package javafx.animation.Timeline can not only be used for animations but for doing things in the background at in interval.
Timeline variable
        var t = Timeline { ... }
        t.start();
    
...or standalone if you don't need to reference it later on:
Timeline on it's own
        Timeline {
            repeatCount: Timeline.INDEFINITE
            keyFrames: [
                KeyFrame {
                    time: 1s
                    action: function():Void {
                        ...
                    }
                }
            ]
        }.start();
    

Binding with if statement

Binding is a really nice feature that I appreciate a lot. Not only can you bind it one way with just bind, two ways with the bind X with inverse, but you can also use an if statement.
bind if
        Rectangle {
            fill: bind if(progress >= warningThreshold) then barFill else barWarningFill
        }
    
Read more about binding at the PlanetJFX wiki.

Formatting text

Not everything is present in the current preview release of the SDK. I'm guessing that a simple way of formatting will be there in the future, but for now we'll have to use the standard java.text.* classes for this. Not that it's such a burden, but beeing able to write "{total format as <<#,##0>>}" which is mentioned in the PlanetJFX FAQ would of course be nice.
Formatting a number
        import java.text.DecimalFormat;
        var numberFormatter: DecimalFormat = new DecimalFormat(".00");
        numberFormatter.format(numberVariable)
    

What I'm missing

There are mainly two things I've been missing when I've worked with JavaFX. The worst is the lack of design tools. JavaFX is of course a competitor to Flash and Silverlight, but I don't think it'll ever be mentioned in the same context as Flash by any other than Java developers unless we have a real design tool. At least a tool that has the ambition to be used by non programmers.

It would also be nice to have better IDE support. Don't get me wrong, NetBeans is a great IDE, but it has spoiled me. Things like fix imports and code formatting isn't working for JavaFX Script code. Code completion is a bit off as well. But hey, it's a preview release of the SDK so I guess it's a work in progress.

There's also a little thing that I find annoying after the API changes. JavaFX Script went through a change from an interpretated language to a compiled one not so long ago. Not surprisingly some changes were made to the API thanks to this. The annoying part is that a lot of examples one can find out there is still in the old format. PlanetJFX has a page about converting to the new syntax that covers some of it. This will of course be fixed over time since new tutorials and examples will be produced. However, people new to the langauage might be turned off when they find that every now and then there is a piece of code they copy from an example that just can't work.

Conclusion

Not much needs to be said other than to repeat what I've stated earlier. JavaFX Script is quite fun and WidgetFX is a nice way to get into it. Not to mention that the actual widgets have a good potential to be really useful.

  • Update Jan 8 2009: Updated to JavaFX SDK and WidgetFX 1.0, plus added a launch button:



Re: JavaFX, WidgetFX and my first widget

There's also a thread here to follow with some comments: http://groups.google.com/group/widgetfx-dev/browse_thread/thread/273b747290daa9f6

Re: JavaFX, WidgetFX and my first widget

Hi, Can you post the source code to refer your effort?

Re: JavaFX, WidgetFX and my first widget

I think I'll will post the source code in the future. Honestly it's quite ugly and I would like to get the base features working first. Therefore it'll take a while, especially since I haven't had much time for it.

Re: JavaFX, WidgetFX and my first widget

Pär, Time to jump back into WidgetFX! Version 1.0 was released today: http://javafxpert.com/weblog/2009/01/create-widgets-in-javafx-with-newlyreleased-widgetfx-10.html Thanks, Jim Weaver

Re: JavaFX, WidgetFX and my first widget

That's funny, I think I uploaded a new version of DiskSpace Widget for JavaFX & WidgetFX 1.0 just about the same time as I got your comment :)

Add a comment Send a TrackBack