Definition Building Blocks

GUIKit definitions are defined as a hierarchy of widgets, whether they are defined in the Mathematica expression format or in the XML format, GUIKitXML. A single self-contained user interface definition should always begin with an outermost user interface widget—either an instance of a window or frame. The GUIKit framework also optionally provides an appropriate top-level window wrapper if the root interface definition widget is at least a user interface class that can live inside a window or frame, so you are not actually required to always use a top-level frame or window widget. This is convenient because it allows you to write reusable complex widgets by designing them with the root widget as Widget["Panel"]. This could be run by itself or reused as content in other developers' window definitions. Examples of reusing panel-designed higher-level widgets exist in subsequent documentation sections.

A GUIKit definition expression consists of a hierarchy of widget expressions.

Some of the building blocks that make up a user interface definition include the following.

Request the creation of a new widget instance.

Click for copyable input

Reference an existing widget previously registered under (using the option).

Click for copyable input

Mathematica scripting code blocks contain arbitrary Mathematica programming code executed within the context of the user interface instance with access to the widget objects defined in the user interface.

Click for copyable input

Event binding provides triggers for Mathematica code to execute when certain events happen within the user interface.

Click for copyable input

Set or get the state and values of live widgets in the interface.

Click for copyable input

If the widget definition requires arguments when it is created, you can set these with InitialArguments.

There is an equivalent set of XML elements that define a user interface definition analogous to the previous Mathematica building block expressions.

Widget Layout

GUIKit definitions are defined as a hierarchy (a "tree" expression) of widgets, but at the same time the definition's nesting structure and list depth also determine how the widgets will visually lay themselves out at runtime. The goal of the layout rules is to make the most common and useful forms easy to represent in the definition, and at the same time provide the necessary optional rules to allow for finer control over the layout. Additionally, the layout rules follow familiar Mathematica list structures and do not require knowledge of the underlying Java rendering implementation layout APIs. This high-level abstraction of determining layout provides a simple, immediate, and intuitive layout as well as the necessary dynamic layout resizing features that all modern user interface dialogs are expected to adhere to when resized.

In[33]:=
Click for copyable input

You can achieve most of the desired layout appearance of interface definitions by simply nesting widget expressions within other widget expressions and choosing the desired level of {...} nesting to determine the resulting automatic vertical or horizontal grouping.

The following basic heuristics are followed in the GUIKit widget layout system.

  • The outermost (top-level) list of widgets, children in Widget[comp, children_List], defaults to using a vertical (column) layout.
  • Each subsequent nested list alternates between a horizontal (row) and vertical (column) layout.
    • Each type of widget has its own default horizontal and vertical stretching characteristics. For example, text fields automatically stretch in the horizontal direction but not vertically.

    Here are some examples of these default layout features.

    By default, a list of children widgets is laid out vertically in a column starting from the left edge of the panel.

    In[34]:=
    Click for copyable input
    In[35]:=
    Click for copyable input
    Out[35]=

    Nesting lists within a vertical layout creates horizontal layouts of these internal groupings.

    In[36]:=
    Click for copyable input
    In[37]:=
    Click for copyable input
    Out[37]=

    Further nesting alternates with vertical and horizontal layout nesting.

    In[40]:=
    Click for copyable input
    In[41]:=
    Click for copyable input
    Out[41]=

    Here you see how certain types of widgets default to maximize their sizes over other types of widgets, which adheres to typical user expectations.

    In[45]:=
    Click for copyable input
    In[43]:=
    Click for copyable input
    Out[43]=

    Note that with the new size of the window, the defaults cause the text field to resize horizontally, while the text area expands in both directions.

    In[46]:=
    Click for copyable input
    In[47]:=
    Click for copyable input
    Out[47]=

    When simple nesting of widgets is not enough to achieve the desired layout or resizing characteristics, there are a number of additional Widget interface definition expressions and options that can aid in tweaking the results. Namely, the additional definition expressions include WidgetGroup, WidgetFill, WidgetSpace, WidgetAlign, and the Widget and WidgetGroup options that can choose alternate default values for features, such as , , , , and elements.

    These additional expressions and options are introduced through the following visual examples.

WidgetGroup

When the default layout alignment based on the depth of the list nesting is not appropriate, you can use the form WidgetGroup[{...}, WidgetLayout->Row] or WidgetGroup[{...}, WidgetLayout->Column] to explicitly specify the next alignment.

WidgetGroup[{...},WidgetLayout->Row]
explicitly force a horizontal layout of the child widgets
WidgetGroup[{...},WidgetLayout ->Column]
explicitly force a vertical layout of the child widgets

The basic forms of WidgetGroup usage.

WidgetGroup[{group1,group2,...},     WidgetLayout->{"Grouping"->{Tabs,{"Tab Label1","Tab Label2",...}}}]
place the labeled tabs at the top of the generated tab pane
WidgetGroup[{group1,group2,...},     WidgetLayout->{"Grouping"->{Tabs,Bottom,"Tab Label1","Tab Label2",...}}}]
place the labeled tabs at the bottom

Groups displayed in tabbed panes.

WidgetGroup[{group1,group2},WidgetLayout->Split,Name->"mySplitPane"]
place a resizable split bar between the two groups and optionally name the generated split pane as
WidgetGroup[{group1,group2},WidgetLayout->{"Grouping"->{Split,Vertical}}]
use a vertical split bar
WidgetGroup[{group1,group2},WidgetLayout->{"Grouping"->{Split,Horizontal}}]
use a horizontal split bar

Groups displayed in split panes.

WidgetGroup[{{...},{...},...},WidgetLayout->Grid]
use a grid of evenly aligned elements as an alternative to multiple nested row and column lists (but this form has some limits as to resizing and staggering of child widget lists)

Grid-based groupings.

You can override what would normally be a vertical layout by explicitly choosing a top-level row layout.

In[48]:=
Click for copyable input
In[49]:=
Click for copyable input
Out[49]=

Nested lists still use the automatic alternating horizontal and vertical layouts and so the child list will now be a column.

In[51]:=
Click for copyable input
In[52]:=
Click for copyable input
Out[52]=

You can explicitly replace any and all lists of widgets with WidgetGroup expressions.

In[53]:=
Click for copyable input
In[54]:=
Click for copyable input
Out[54]=

Here you see an example of the grouping.

In[55]:=
Click for copyable input
In[56]:=
Click for copyable input
Out[56]=

Here is an example that generates content within a set of tabbed panes.

In[57]:=
Click for copyable input
Out[57]=
In[58]:=
Click for copyable input
Out[58]=

Each element of the tabbed WidgetGroup can be a list of widgets that populate one tab panel or a single widget whose contents will be placed within one pane.

In[59]:=
Click for copyable input
Out[59]=
In[60]:=
Click for copyable input
Out[60]=

Here is an example that uses a split pane and illustrates how you can optionally name the split pane so it can be manipulated using its properties at runtime.

In[68]:=
Click for copyable input
Out[68]=
In[62]:=
Click for copyable input
Out[62]=
In[64]:=
Click for copyable input
Out[64]=

If you resize the panel a little larger, you can see that you can programmatically move the divider position.

In[69]:=
Click for copyable input
In[70]:=
Click for copyable input
Out[70]=

You can also call a method by taking a percentage value instead of using the integer property value.

In[71]:=
Click for copyable input

WidgetFill

WidgetFill[] elements can be useful as "expanding springs" that force themselves to expand as much as possible along the layout direction they are placed and force other widgets within their group to be "pushed" to one side.

Perhaps the most common use of WidgetFill[] is to force a set of horizontal buttons to be right aligned in a dialog when resizing.

In[72]:=
Click for copyable input
In[73]:=
Click for copyable input
Out[73]=

WidgetSpace

WidgetSpace[n] elements can be useful as simple spacers that create an explicit spacing element between widgets along the layout direction they are placed.

Here you add a little explicit spacing between the buttons.

In[74]:=
Click for copyable input
In[75]:=
Click for copyable input
Out[75]=

WidgetAlign

WidgetAlign[] elements work as placeholder elements within groups of widget lists, and, for each one that exists within sibling lists, they will attempt to align themselves with other instances of WidgetAlign[], forcing a certain grid structure to exist without forcing the same number of widgets to exist between corresponding align markers. They function somewhat analogously to tab markers in word processing documents.

Another more advanced form of WidgetAlign is WidgetAlign[{"widgetName", After|Before}, Before|After], which specifies that the very next widget following the WidgetAlign should align its beginning or end ( or ) with another widget named along either its beginning or end. This form has somewhat limited use and requires properly named widget dependencies in an appropriate location to work well.

Here you place WidgetAlign[] marker elements where you would like sibling widget lists to align.

In[76]:=
Click for copyable input
In[77]:=
Click for copyable input
In[78]:=
Click for copyable input
Out[78]=

WidgetLayout Options

As you have seen earlier, is an option for WidgetGroup that can specify the grouping directions for the containing widgets. Actually, this form of WidgetLayout->groupValue is a shorthand form for . As it turns out, there are a number of different suboptions of that provide different tweaks to layouts. The short form for grouping is available as it is very common to only use to specify a grouping choice.

One other short form use of is used with Widget and that is for the special case when you want to create a user interface widget, but you do not want to have the widget automatically added to the layout of its parent widget. In this case, you would turn off any widget layout work using WidgetLayout->None.

WidgetLayout->groupValueshorthand form of
WidgetLayout->Nonean option to Widget to turn off any automatic interface layouts with its parent widget

Forms of use.

Along with , which allows all forms previously documented for the short form of : , , , Automatic, and None, the following other suboptions exist.

"Grouping"

"Grouping"->groupValue takes on all grouping values documented for short forms mentioned so far, and this suboption form must be used when combined with other suboptions for a given WidgetGroup.

See examples of WidgetLayout->groupValue in the previous sections for examples of use.

"Stretching"

The suboption is supported both for Widget and WidgetGroup and is useful to specify an explicit horizontal and vertical stretching for a widget that may be different than the default stretching characteristics for a given widget type. Both a horizontal and vertical stretching value can be specified with allowable values: None, False, WidgetAlign, True, and .

"Stretching"->{horizontal,vertical}override any default stretching characteristics for a given widget
"Stretching"->Nonekeep a widget from stretching from its initial size
"Stretching"->Falsesame as "Stretching"->None
"Stretching"->Trueallow stretching, but another widget with Maximize stretching may limit stretching if it exists
"Stretching"->Maximizeallow stretching and also prioritize this widget's stretching over others that may simply allow stretching
"Stretching"->WidgetAlignallow stretching, but only to the extent needed to make a widget the same size as sibling widgets in its list

Uses of suboption.

By default, labels do not stretch and text fields do, but you can override this with explicit values.

In[81]:=
Click for copyable input
Out[81]=
In[80]:=
Click for copyable input
Out[80]=

This is more apparent with a window resize.

In[82]:=
Click for copyable input
In[83]:=
Click for copyable input
Out[83]=

"Alignment"

The suboption is supported both for Widget and WidgetGroup and can be used to specify both horizontal and vertical alignments. The default alignment value along the vertical axis is Left and can take values of Left, Center, or Right, and alignment on the horizontal axis defaults to Center, allowing values of Top, Center, or Bottom. Using Automatic for either of these axes will choose the appropriate default.

"Alignment"->{Automatic,Automatic}equivalent to "Alignment"->{Left, Center}.

Uses of suboption.

It is very common to have a set of labels for text fields right align with the corresponding input fields.

In[84]:=
Click for copyable input
In[85]:=
Click for copyable input
Out[85]=

"Border"

The suboption is a convenient way of building common border styles around groups of widgets. Three common types include borders specifying spacing only, a titled border with a name and ruled frame, and a simple line border with a thickness and optional color value.

"Border"->"title"create a titled border style with a ruled outline
"Border"->{{left,right},{top,bottom}}create a border of spacing different for each of the four edges
"Border"->ncreate a spacing border of equal margins in all directions
"Border"->{color,n}create a framed line border of thickness n with color
"Border"->{color,{{left,right},{top,bottom}}}
create a framed line border of different edge thicknesses with color
"Border"->{border1,border2,...}create a compound border style with each of any possible border styles nested together

Uses of suboption.

Here is a simple titled border.

In[86]:=
Click for copyable input
In[87]:=
Click for copyable input
Out[87]=

Note that some widgets, especially Widget["Panel"], can set a "border" property directly, and so a widget layout option can be specified directly with some widgets.

In[88]:=
Click for copyable input
In[89]:=
Click for copyable input
Out[89]=

You can add a little inner spacing with a compound border of a title with a spacing border.

In[90]:=
Click for copyable input
In[91]:=
Click for copyable input
Out[91]=

Here we have added a simple red border three points thick.

In[92]:=
Click for copyable input
In[93]:=
Click for copyable input
Out[93]=

"Spacing"

The "Spacing"->n suboption allows a WidgetGroup to specify an overall spacing element to exist between all widgets in the group.

Here you have forced a spacing of 30 points between all widgets in the group.

In[94]:=
Click for copyable input
In[95]:=
Click for copyable input
Out[95]=
New to Mathematica? Find your learning path »
Have a question? Ask support »