Andy has posted 1 posts at DZone. View Full User Profile

Glimmer - Using Ruby to Build SWT User Interfaces

06.19.2008
| 51976 views |
  • submit to reddit
Given that Glimmer relies on the Eclipse SWT library, developers may consult the SWT API as a reference on all the widgets, including their properties and layout options: http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/reference/api/index.html

Keep in mind the following rules when reading the SWT API:

  • Any widget available in SWT, including custom widgets written by developers, can be accessed from Glimmer by downcasing/underscoring the widget's name (e.g. Composite -> composite, LabledText -> labeled_text)
  • Properties available on SWT widgets are specified by listing them followed by their values, each on a line or separated by semicolons within the widget's block (e.g. label {text "Username:"; font some_font}) Property names are also downcased/underscored in Glimmer.

SWT widgets must have a style value specified, which is a constant available on the “SWT” class. Glimmer generally hides that by relying on smart defaults.

Here is a listing of the defaults configured in Glimmer:

text: SWT::BORDER
table: SWT::BORDER
spinner: SWT::BORDER
button: SWT::PUSH

Nonetheless, to customize a widget, a style value may be optionally specified within parentheses after the widget name. For an example, “button(SWT::RADIO)” renders a radio button and “button(SWT::CHECK)” renders a checkbox button.

Glimmer's syntax also has syntactic sugar for specifying the style. Simply state the name of the style in the standard Ruby downcased/underscored format without the “SWT::” prefix. For example, button(SWT::RADIO) becomes button(radio).

SWT composite widgets, such as shell, composite, and group can have a layout manager that lays out child widgets according to a certain pattern without the need to specify the (x, y) position of each child widget explicitly. Layout managers come in many flavors, such as GridLayout, offering a grid-like layout; FillLayout, allowing child widgets to fill the whole available area; and RowLayout, rendering child widgets one after the other in a row by default.

Glimmer is configured with smart defaults for layout managers too:

shell: FillLayout
composite: GridLayout with one column
group: GridLayout with one column

GridLayout is a particularly useful SWT layout, so I will go over it in a little more detail here. GridLayout allows you to lay widgets out in a grid similar to HTML tables. To instantiate a custom GridLayout, you must specify the number of columns and whether they are of equal width or not. Here is a block of code demonstrating a group box having a GridLayout with 2 columns of unequal width:

group {
 layout GridLayout.new(2, false)
}

Now, suppose we add four elements to that group box:

group {
  layout GridLayout.new(2, false)
  label {text "First"}; 
  text {text "Bullet"}
  label {text "Last"}; 
  text {text "Tooth"}
}

 The specified GridLayout will lay out the child widgets in the grid from left to right and top to bottom:

  • The label with the text “First” will go into the 1st column of the 1st row.
  • The text box with the text “Bullet” will go into the 2nd column of the 1st row.
  • The label with the text “Last” will go into the 1st column of the 2nd row.
  • The text box with the text “Tooth” will go into the 2nd column of the 2nd row.

The group was actually a part of the advanced example illustrated earlier. It was given a title (by specifying the text attribute,) and the widget declarations were written in a way that maps visually to how they appear on the screen. Notice how text box declarations are on the same line as the label declarations since both the label and text box go under the same row, which helps improve code readability and maintainability:

group {
  text "Name"
  layout GridLayout.new(2, false)
  layout_data GridData.new(fill, fill, true, true)
  label {text "First"}; text {text "Bullet"}
  label {text "Last"}; text {text "Tooth"}  
}

That renders the following:

Published at DZone with permission of its author, Andy Maleh.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)