: Core concepts

 

This page uses the spike applet to introduce the core concepts underlying the Superficial approach to designing and coding GUI applications.

Communicating with an application - the surface

What do you see when you look at the spike applet?

 

You may answer that you see an applet or application, or more specifically the user interface to an application. However 'user interface' can refer to anything from a functional and aesthetic design to a particular arrangement of platform widgets.

Superficial gives a more definite answer to this question:

  • You the user are on the outside of an application.
  • You need to interact with content that is inside the application.
  • The element that enables interaction between the inside and outside of an application is most helpfully described as its surface.

The metaphor of surface leaves open the exact means by which a surface manages interaction between user and application, but it is easy to decide whether an application has a surface. A GUI is evidently a surface, but so is a command-line interface or even a teletype.

Defining a GUI surface - facets

How does the surface metaphor help with the practicalities of developing GUI applications?

Superficial views a GUI surface as composed primarily not of its low-level widgets, but of facets that expose elements within the application. Each facet creates and manages a a group (usually) of widgets, updating their state as required to match the application element the facet exposes, and relaying input from the widgets to the application.

By mediating between the GUI widgets and the application, facets make possible the key Superficial mechanism of retargeting. They also greatly reduce the number of GUI elements that need to be specified by application code. Even the simple GUI surface of the spike applet comprises nearly 140 Swing components, but these are built and managed by only around 50 facets. For instance:

  • a textual facet uses a text field to expose the text of the currently selected text line object
  • a toggling facet uses a Font sub-menu to expose text line style flags, while activating the Font tool panel reveals another that does the same using a checkbox panel
  • a trigger facet in the tool panel exposes line selection with a pair of buttons , while another does the same with a pair of Line menu items
  • indexing facets use Font sub-menus to expose the font face
    , size
    and shade ; while in the tool panel others expose the same values using a radio-button panel ,
    a drop-down list combined with indexing buttons ,
    and a list box
  • a single numeric facet in the Position tool panel manages sliders and associated text fields for both the X and Y positions of the selected text line, while another exposes the same values using a button panel that has its counterpart in Line menu items

The fact that facets usually manage more than one widget is a major benefit of the Superficial approach - developing a GUI is much easier if you don't have to specify each and every button, label and menu item.

Behind the facets - targets

Developing a GUI surface with Superficial is easier in another way.

Superficial defines each facet as exposing a target in the application. Targets may represent a simple data value, an action, a complete content structure, or even an element of the surface itself such as a viewer or window. The retargeting mechanism described below transparently connects facets to targets both during construction of the GUI and in response to events such as change in selection

Each target in the application may be exposed by any number of facets in the surface. This means that many fewer targets are required than facets, while each facet may bind several widgets to the data represented by its target.

In the spike applet and spike application the ratios of targets, facets and widgets are as shown below:
 
    Targets   Facets   Widgets
Spike applet   22   54   137
Spike application   70   114   321


Both facets and their targets can be defined semi-declaratively, allowing Superficial GUIs to be defined with the same simplicity as JavaFX Script but with the advantages of

  • GUI definition within Java - no special language
  • conciseness - each facet manages a complete group of widgets

Manipulating content - the viewer facet and its targets

To see how Superficial makes it much easier to define the interactions that make for a rich, responsive GUI, let's look at how the spike applet responds to user interaction with its viewer.

Superficial regards the viewer as being a facet that exposes a viewable target acting as a frame for application content, here an array of three text line objects; it also has a view target defining graphical avatars for the content.

When the spike applet opens, none of the text line avatars is selected and most of the tools and menu items are disabled. Click on the avatar for a text line and a bar appears beneath it.

The avatar now depicts a selection target within the viewable target of the whole viewer. At the same time the tools panel and menu items respond by becoming enabled and exposing the values for the same selection target.

Drag the selected text line to a new position,

and the Position facets in the tools panel are updated to match the new values.

Drag the far end of the text line avatar to change its angle,

and the tool panel switches to the Angle tools, which are updated with the angle of the selected text line.

As you change the selection target by clicking on another avatar or a Line iteration button, the tool panel and menu items are updated to match the newly selected text line. And if you change the properties of a text line using the tools panel or menus, its avatar in the viewer is updated to match.


This responsive behaviour is intuitive in user terms, but far from straightforward to code:

  • Tool panel and menu widgets must always display the properties of the selected text line.
  • User input via tool panel or menu widgets must result in corresponding updates to the viewer, and vice-versa.
  • The GUI as a whole must respond to interaction in the viewer by switching tool panel widgets etc.

To put the problem in general terms, a GUI application has to ensure that it maintains view consistency at all times.

Coding a GUI using conventional methods that meets this requirement can be a struggle; Superficial's concepts of surface, facet and target make possible the retargeting mechanism that makes it almost a pleasure.

Oh, and it's a reasonable guess that the cow jumped over the moon.

Retargeting - the key Superficial mechanism

Superficial maintains view consistency (as demonstrated in the spike applet and spike application) by treating the complete GUI surface as an integrated view of the application and its content. Refreshing this view to match the state of the application is achieved by retargeting.

The facets that create and manage GUI widgets are connected to their targets in the application via a targeter tree created by the surface (and visible in the debug pane). After any significant application event all facets are retargeted via the targeter tree on appropriate targets, thus synchronising all widgets with the latest application state. Each facet uses the event handling of the GUI toolkit to listen for input on its widget(s) and interpret this input in relation to its current target.

Application events that trigger a retargeting include the initial construction of the GUI surface, and any action by a facet on its target in response to GUI events.

Retargeting is largely transparent to client code, enabling you the developer to let Superficial take care of the two major issues of GUI development: binding widgets to data and listening on events.

  • Data binding is automatic - when retargeted initially or in response to an application event, each facet updates its widgets to match its current target, and thus to the content or other application object represented by that target.
  • Event handling is hidden - each widget need only communicate with its managing facet, which will relay input from the widget to the facet's current target in the application.

Given the update speeds of modern GUI toolkits, retargeting has minimal impact on the latency of an application surface: in the spike applet a full retargeting takes place every time you pause a drag or slider movement.

Construction of the targeter tree is handled transparently by Superficial. Each contenter in a Superficial application need only define target and facet trees for its content, and its containing surface constructs a suitable targeter tree to connect them.

Defining the surface - contenters

The transparency to client code of retargeting makes it possible to encapsulate the definition of surfaces and thus of complete applications.

Take a look at the code in the code viewer applet, and you will find that surface elements are always defined by contenters that wrap the application content. A contenter defines

  • targets representing both its content and surface elements such as panes and windows
  • facets defining GUI widgets for viewers, menus and tool areas that expose these targets to the user

Simple applications such as those in the tutorial can be constructed using specialised contenters, while even a multi-viewer, multi-content type application such as the spike application is surprisingly easy to define.

Retargeting in action

You can view retargeting in the spike applet and code viewer using two different debug options.

Toggle the Graph checkbox below the spike applet and the viewer pane splits into two.

In the left-hand pane you can still interact with the viewable content, while in the right-hand pane you can monitor the state of the targeter tree.

Expand the bottom, 'selection' node of the targeter tree far enough,

and for each property of the currently selected text line you will find

  • the targeter for the property
  • its current target representing the property
  • the property value itself
  • the facets attached to the targeter, exposing the target and thus the property

Change or move the text line and the targeter tree adjusts to match.

The other debug option allows you to watch the retargeting sequence that updates the targeter tree and the facets attached to it.

Open the Java console for your browser and toggle the Trace checkbox below the spike applet. The applet reopens and you can watch the targeter tree being created, then the retargeting that takes place after each input to the surface.

The power of Superficial - separation of concerns

Because a Superficial surface is defined purely in terms of facets, targets and the targeter tree that mediates between them, interactions between application elements are very clearly defined.

  • A GUI widget interacts with its managing facet only to notify user input.
  • While viewer facets interact directly with the domain content framed by their viewable targets, simple facets interact only with their targets.
  • The targeter tree interacts with both facets and targets through very narrow interfaces.
  • A target interacts actively only with the application element it represents.
  • Application content has no knowledge of the surface that enables the user to interact with it.

This strong separation of concerns ensures that Superficial applications are inherently easy to develop, debug and maintain.

 

© 2007 David M Wright