• Home
  • Events
  • About
  • UI Construction with JavaFX

    When constructing a UI then on the technical level I am concerned with
    - creating the respective widgets
    - putting them in the right place, i.e. layouting
    - making them look nice and consistent, i.e. styling
    - hooking them up to the data they should display, i.e. binding
    - and putting them to action, i.e. attaching handlers.

    Creating the widgets

    The usual way of creating widgets like labels, buttons, menus, tables, charts and the likes is by calling their respective constructors.
    Alternatively, one can use factory methods like in Swing to either set some common attributes consistently on each widget or to even construct compound components like a labelled text field.
    JavaFx provides additional Builders for creating preconfigured widgets by following the classical GOF Builder pattern with additional create() and build() methods.

    Layouting

    Where Swing puts its components inside containers, JavaFX adds its nodes to a parent node in the SceneGraph. Either way, layouts define how the added widgets are placed inside the available area: side-by-side, stacked on top of each other, in the cell of a grid, in equally sized tiles, or else.
    Layouts also have their own strategies of reacting to changes in the available area and how they deal with missing or excessive space.

    Selecting a layout and putting each widget in its proper place can be done by API calls or via an external description in XML format (FXML).
    GroovyFX adds the additional capability of defining the layout with tree-like builders as part of the usual code.

    Styling

    Swing styling was confined to API calls that would set visual properties per-widget (plus rules for proliferation of these property values down the containment tree) and the Look&Feel concept.
    JavaFX builds on top of the API approach with CSS-like styles. This adds a fully new magnitude of power to the visual design capabilities but also a new dimension of complexity. Without going into too much detail, here are some points to consider:
    - CSS has its own notion of cascading and how to “inherit” values
    - JavaFX supports multiple stylesheets per scene plus “inline” styles per node
    - selectors are per id, node type, and/or styleClass plus some pseudo-classes
    - styles, styleSheets, styleClasses, and API-controlled properties may change at any time

    Layout styles

    To make things even more complex, it is not only the widgets that have visual properties like a Label bearing Font. Even layouts have styles, e.g. values for paddings, margins, gaps, alignments, etc. (but not for positioning ATM).

    Binding

    The binding story in JavaFX follows the same approach as Swing does by registering listeners that get notified for value changes of any bindable source. Such a source is typically a data model or some other widget. The latter case has a special support in JavaFX through accessor methods that end with “Property” and provide a very efficient update mechanism.

    Projects like GroovyFX add on top of that concept further capabilities for declarative binding.

    Event handlers

    Value changes are not the only events that one can listen for. A long list of registration methods for callbacks that start with “on” are at our disposal for setting the application in action: onAction, onKeyReleased, onMouseOver, etc.
    Quite surprisingly has JavaFX chosen to only support one such event handler per registration. We cannot add to an existing list of those unless we build such a facility ourselves.

    Organizing the codebase

    With all the work of creating, layouting, styling, binding, and event handling comes the need for some organization.
    - there are sequence dependencies between these tasks
    - there is scope to be managed to keep reference usages traceable
    - styles, layouts, and whole building blocks may be shared for faster building, consistency and less maintenance effort

    In other words, we need some grouping that keeps these aspects together while making them distinct enough such that each part is easily recognizable, potentially reusable, and subject to proper lifecycle management.

    Use Griffon when you can

    The Griffon framework provides a full solution for this challenge with its organization into MVC groups and the rules and conventions that it imposes on the code structure.

    For those of us who do not have such a luxury: down below is a proposal for a simple structure that can help keeping track of the various aspects.

    Example: a simple feedback form

    We start with a simple example of a feedback form that looks like this:

    All-in-one

    We can implement this form easily in GroovyFX by putting all the UI code (widgets, layout, style, behaviour) in one single place.
    Here is a possible solution.

    https://github.com/groovyfx-project/groovyfx/blob/develop/groovyfx/src/demo/groovy/structure/AllInOne.groovy

    Having everything in one place has its advantages: at least you know where to start looking.
    But it comes at the expense of clarity and consistency, e.g. the initial example makes all labels to be of white color.
    Is that by accident or shall that be a consistent rule – a common style? This is most likely.

    Separating the various aspects into their own methods also provides a better overview about
    - what widgets we are dealing with
    - how they are arranged on the screen
    - what dependencies they have (binding)
    - and what they are supposed to do.

    The better structured code becomes this:

    https://github.com/groovyfx-project/groovyfx/blob/develop/groovyfx/src/demo/groovy/structure/Improved.groovy

    Pretty much all styling information is out of the way and can be maintained in an extra class or css file – and used in multiple places.

    https://github.com/groovyfx-project/groovyfx/blob/develop/groovyfx/src/demo/groovy/structure/DemoStyle.groovy

    http://github.com/groovyfx-project/groovyfx/blob/develop/groovyfx/src/demo/resources/demo.css

    Having the styles in one place makes it often more worthwhile to improve the style. Here we worked a little on the background gradient and added an additional feat that makes the form scroll-in at startup – just as if you would be handed over a feedback form from someone who sits in front of you.

    This is how it looks now:

    structured

    This is the end of the story for today but not for tomorrow. Further improvements of this structure are likely to be needed for any project of size.

    stay tuned
    Dierk König, @mittie

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • DZone
    • Y!GG
    • Webnews
    • Digg
    • del.icio.us
    • DotNetKicks
    • Facebook
    • Google Bookmarks
    • Newsrider
    • Twitter
    • YahooBuzz

    1 Comment »

    1. url submission said,

      February 21, 2012 @ 11:35

      Very descriptive post, I enjoyed that bit. Will there be a part 2?

    RSS feed for comments on this post · TrackBack URI

    Leave a Comment


    × 2 = six

    css.php