Evolving Swing Through Simplification

DZone 's Guide to

Evolving Swing Through Simplification

· Java Zone ·
Free Resource

The snippet that I'm about to propose today is very different from what you've got to enjoy, I hope, in the previous article. While the Ping-Pong example, through an imperative training method, has put in shape (after all, we are talking about sports) those mainly interested in Concurrent Programming, the one of today, which instead uses a declarative style, should stimulate interest of the developer of Desktop Applications. Of course, the purpose of this "ping-pong" between Concurrent Programming and GUI Programming is not for confusing or surprising the reader, but rather for supporting Givvy as a real general-purpose language (at client side).

Two words on Commands

Givvy provides a declarative syntax for interfacing with the language APIs. Specifically, the {} delimiters indicate the definition of a command, which acts as a proxy object to the functionality of a Java Class.

A command can be dynamic, when it determines the generation of an object -- here an instance of the Swing class JSpinner -- having a state that can be modified over time through its reference,

spinner-120x50.png spinner-500x120.png

or static, if the Java Class that implements the service does not have a persistent state. For example,


A command is uniquely defined by the name of the Module -- a collection of logically related commands -- to which it belongs, and by the name of the service it provides. So, the "Spinner" service is a command provided by the ui Module, while the "read" service by the json Module.

What I would stress here is that any Java developer can easily extend a GVision node with a new API, due to the fact that commands are, actually, OSGi services under the hood. All Modules, indeed, are implemented as OSGi Bundles.

Since Givvy is a concurrent programming language, it's important to point out as well that any dynamic command runs always and only inside the scope of the domain (Core) where it was defined. This also happens in the event a command would be passed, through a message, to a Task placed in another domain.

A basic UI application


I will not go here into the details of this basic program (slightly modified in Givvy from a starting JavaFX tutorial), but basically the position of "painter" depends on the value assigned to "slider" and "spinner". It's a very simple program, but exemplifies in a clear way the general structure of a Givvy application that exposes a user interface.



As you can see, though ready to be delivered to the GVNode (the client side) or incorporated in a larger concurrent application, it's still much simpler to read than any minimal Swing-based program.

It uses the static command ui.manager to control the "current window", while the "current container" is implicit. With the ui.manager command you can also set a different "current window" or a different "current container". Of course, the Givvy UI Toolkit still provides a ui.Window and a ui.Panel.

How to layout widgets

A prominent aspect of the Toolkit is that has completely eliminated the need for layout managers. In my opinion, one of the most challenging concept to master in Swing/AWT.

The Toolkit, instead, has adopted an approach based on positioning and sizing a widget in relation to its container -- for example, a widget dynamically increases its size when the container in which is inserted is also increased --, or in relation to other widgets within the same container, by means of a very simple DSL. The widget, this way, can be placed and sized within the container by only using a few properties (alignment, location, x, y, size, width, height, bounds), and simple expressions such as :

  • align "spinner" to the right of the container and then move it to the left by another 20 pixels,
    and place it ten pixels under "slider"

  • set the width of "painter" equal to 90% of the width of "slider" layout2-290x32.png

In total, the DSL implements the 4 basic math operations and more than 30 functions (left, right, top, bottom, maxWidth, range, xFraction, ...).

You can also use the ui.Form container for laying out widgets. This is a powerful and flexible component which can also contain other Forms (that is, they can be nested). I'll show it in the next post.

Data Binding

Givvy has a built-in Data Binding mechanism which comes into play using the <| operator, and which is applicable to any language identifier, as well as to any boundable property of a dynamic command.


As you see, the left value (as to the <| operator) can be updated according more right values by separating them with the | operator.

Optionally, using the -> operator, you can also add to the expression a code block which gets executed every time any of the right values is updated. -- _it is a constant provided by Givvy, taking whatever right value, in this case "slider.value" or "spinner.value", should be modified. After the assignment to _it, the sum operation is performed and the result assigned to "painter.x" --

Placing the > symbol after the pipe you can also activate one or more bidirectional bindings.


In this case, changing "spinner.value", the x variable is not modified.


How to deploy the program on a cNode server

This is really demanding.

Place BidiBind.gvy in the files folder of your cNode installation.

How to run the program at the client side

Even this is quite demanding.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}