Scala Programming
A programmer's blog
A distinguishing feature of the Groovy programming language is its builders.
A Groovy builder lets you imbed hierarchical structures directly into your
code. Groovy supports a range of builders including XML builder, Ant builder
and Swing builder. The Grails web application development framework, built on
Groovy, also supports JSON and Hibernate criteria builders. Interestingly, this
range of builders is developed from a single common framework.
Builders offer a convenient way to construct hierarchical models with a direct
correspondence between the hierarchy and the generated code. The following
snippet demonstrates how, using a Scala
simple UI:
Simple widgets such as
of named parameters. The property is identified with a
value. Container widgets such as
of the sub-components managed by it.
The widgets are named after their Swing counterpart. Hence the method call
methods have two variants as illustrated by
version initializes the given
widgets. Both calls are also supplied with an implicit
responsible for the creation an initialization of the widgets. For example, the main panel
above might use the custom class
with a gradient painter:
To interact with the application we introduce event handlers through the same
named parameter mechanism. The names are the event handlers of the corresponding
Swing listener class. Pressing a button or entering RETURN into a text field
produces an
registered
In the above application we introduce the synthetic property
second text field. The implicit
the id and the widget which can be retrieved with the method
The first text field includes the synthetic property
The value for this property will refer to a Scala function. The
creates an instance of a class that refers to this function. The class implements
the Swing
The instance of the class is registered as a listener on the text field.
The event handlers are simple Scala functions:
The builder code is, of course, just Scala. We are, therefore, free to mix in
any other Scala code. The factory methods return a reference to the widget it
creates so we could, for example, say:
then use this identifier elsewhere, providing we respect the usual scoping
rules.
The project is very much in its infancy. Presently the library supports
a sizeable subset of the Swing components: label, textField, button, toggleButton,
checkBox, radioButton (buttonGroup), list, scrollPane, panel, tabbedPane
and frame. More will follow.
In the next blog I will show how to introduce an MVC architecture into an
application.
A Groovy builder lets you imbed hierarchical structures directly into your
code. Groovy supports a range of builders including XML builder, Ant builder
and Swing builder. The Grails web application development framework, built on
Groovy, also supports JSON and Hibernate criteria builders. Interestingly, this
range of builders is developed from a single common framework.
Builders offer a convenient way to construct hierarchical models with a direct
correspondence between the hierarchy and the generated code. The following
snippet demonstrates how, using a Scala
SwingBuilder, we might specify asimple UI:
frame('title -> "Centigrade to Fahrenheit conversion", 'location -> new Point(100, 100), 'size -> new Dimension(500, 300)){
panel('layout -> new MigLayout("fill")){
panel('constraints -> "dock north", 'layout -> new MigLayout("fill")) {
label('text -> "Centigrade to Fahrenheit conversion", 'constraints -> "alignx right")
}
panel('layout -> new MigLayout("fill")) {
label('text -> "Centigrade")
label('text -> "Fahrenheit", 'constraints -> "wrap")
textField('text -> "", 'columns -> 20)
textField('text -> "", 'columns -> 20, 'editable -> false)
}
panel('constraints -> "dock south", 'opaque -> false) {
button('text -> "Close")
}
}
}Widgets are created by factory method calls into the SwingBuilder object.Simple widgets such as
label initialize their properties through a seriesof named parameters. The property is identified with a
Symbol and its initialvalue. Container widgets such as
frame and panel also include a code blockof the sub-components managed by it.
The widgets are named after their Swing counterpart. Hence the method call
frame constructs a JFrame object while label constructs a JLabel object. Themethods have two variants as illustrated by
label:label('property -> value, ...)
label(new MyLabel(...), 'property -> value, ...)The first version creates a JLabel and initializes it properties. The secondversion initializes the given
JLabel. This can be used to introduce specializedwidgets. Both calls are also supplied with an implicit
SwingBuilder objectresponsible for the creation an initialization of the widgets. For example, the main panel
above might use the custom class
RadialGradientPanel to deliver a panel decoratedwith a gradient painter:
panel(new RadialGradientPanel(0.0F, 0.0F, 400.0F, List(0.0F, 0.5F, 1.0F), List(royalBlue, royalBlue4, black)), 'layout -> new MigLayout("fill")) { ... }Running this code produces the application:
To interact with the application we introduce event handlers through the same
named parameter mechanism. The names are the event handlers of the corresponding
Swing listener class. Pressing a button or entering RETURN into a text field
produces an
Action event processed by the actionPerformed method in theregistered
ActionListener object.In the above application we introduce the synthetic property
id into thesecond text field. The implicit
SwingBuilder object maintains a mapping betweenthe id and the widget which can be retrieved with the method
getWidgetIDframe('title -> "Centigrade to Fahrenheit conversion", 'location -> new Point(100, 100), 'size -> new Dimension(500, 300)){
panel(new RadialGradientPanel(0.0F, 0.0F, 400.0F, List(0.0F, 0.5F, 1.0F), List(royalBlue, royalBlue4, black)), 'layout -> new MigLayout("fill")) {
panel('opaque -> false, 'constraints -> "dock north", 'layout -> new MigLayout("fill")) {
label('text -> "Centigrade to Fahrenheit conversion", 'foreground -> Color.WHITE, 'constraints -> "alignx right")
}
panel('opaque -> false, 'layout -> new MigLayout("fill")) {
label('text -> "Centigrade", 'foreground -> Color.WHITE)
label('text -> "Fahrenheit", 'foreground -> Color.WHITE, 'constraints -> "wrap")
textField('text -> "", 'columns -> 20, 'actionPerformed -> doConvert)
textField('id -> "fahrenheitTF", 'text -> "", 'columns -> 20, 'editable -> false)
}
panel('opaque -> false, 'constraints -> "dock south") {
button(new GlossButton(), 'text -> "Close", 'actionPerformed -> doClose)
}
}
}The first text field includes the synthetic property
actionPerformed.The value for this property will refer to a Scala function. The
SwingBuildercreates an instance of a class that refers to this function. The class implements
the Swing
ActionListener interface and its actionPerformed method calls the function.The instance of the class is registered as a listener on the text field.
The event handlers are simple Scala functions:
val doClose = (event: ActionEvent) => System.exit(0) val doConvert = (event: ActionEvent) => { val centigradeTF = event.getSource().asInstanceOf[JTextField] val centigrade = centigradeTF.getText().toDouble val fahrenheitTF = builder.getWidgetID("fahrenheitTF").asInstanceOf[JTextField] fahrenheitTF.setText(((9 * centigrade + 160)/5).toString) }
The builder code is, of course, just Scala. We are, therefore, free to mix in
any other Scala code. The factory methods return a reference to the widget it
creates so we could, for example, say:
val centigrade = textField('text -> "", 'columns -> 20)then use this identifier elsewhere, providing we respect the usual scoping
rules.
The project is very much in its infancy. Presently the library supports
a sizeable subset of the Swing components: label, textField, button, toggleButton,
checkBox, radioButton (buttonGroup), list, scrollPane, panel, tabbedPane
and frame. More will follow.
In the next blog I will show how to introduce an MVC architecture into an
application.

1 comments:
Hi Ken, I'm reading your book "Groovy Programming" but I cannot access the website you mentioned for the software distribution. Could you please upload them somewhere again? Thanks!
Post a Comment