The Kaptain on … stuff

05 Apr, 2009

SwingX busy label demo in Griffon and Groovy

Posted by: TheKaptain In: Development

The first demonstration panel in the SwingLabs demo is for the JXBusyLabel, a simple component that does exactly what it says – inform Users of the application that progress is occurring. The setup is highly configurable, allowing changes to the color, shape and size of the rendered label.

The SwingX demonstration makes use of an inner ‘DetailsPane’ class that nicely handles a lot of the gridbag layout details, but I didn’t really want to spend the extra time Groovifying a perfectly good and already implemented helper class, so I just threw the java code in the Griffon src directory and that was that. Being able to seamlessly mix Java and Groovy is a definite plus, let me tell you. Below is an example of adding a new DetailsPane using the builder DSL, utilizing a GridBagConstants variable named ‘gbc’ and assigning the foreground color based on a model property.

[groovy language=”true” smarttabs=”true”]
genPane = jxpanel(constraints: gbc,
new DetailsPane("General settings:", model.FOREGROUND))
[/groovy]

Here is a side-by-side comparison of Java and then the equivalent Groovy code for creating and initializing a new JXBusyLabel. At first they don’t look a whole lot different, but if you notice, the Groovy version is actually a one-liner, and uses the bind() syntax to set colors based on a model backed property.

[java language=”true” smarttabs=”true”]
label = new JXBusyLabel(new Dimension((int) (W / 2), (int) (H / 2)));
label.getBusyPainter().setHighlightColor( new Color(44, 61, 146).darker());
label.getBusyPainter() .setBaseColor(new Color(168, 204, 241).brighter());
label.setOpaque(false);
label.setHorizontalAlignment(JLabel.CENTER);
[/java]

[groovy language=”true” smarttabs=”true”]
label = jxbusyLabel(
preferredSize: new Dimension(model.W / 2 as int,model.H / 2 as int),
busyPainter: busyPainter(highlightColor: bind{ model.busyColor },
baseColor: bind{model.baseColor}), opaque: false, horizontalAlignment: JLabel.CENTER)
[/groovy]

SwingX contains a specialized button that wraps a color chooser component, and here we can look at the differences between the Java and Groovy syntax for instantiating one. The JXColorSelectionButton class isn’t actually a node made available by the SwingXBuilder, but adding to the builder syntax dynamically is simple to say the least using a call to ‘registerBeanFactory’. Also in the Groovy version, here we’re not directly updating the color on the label, we’re updating the model. While the background color change seems to be correctly updated through the bound ‘baseColor’ model property, it does not repaint automagically. I’m sure there’s a way to do this, it just hasn’t popped up yet.

[java language=”true” smarttabs=”true”]
JXColorSelectionButton baseColBtn = new JXColorSelectionButton();
baseColBtn.setBackground(label.getBusyPainter().getBaseColor());
baseColBtn.addPropertyChangeListener("background", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
label.getBusyPainter().setBaseColor((Color) evt.getNewValue());
label.repaint();
}});
[/java]

[groovy language=”true” smarttabs=”true”]
registerBeanFactory(‘colorButton’, JXColorSelectionButton.class)
baseColBtn = colorButton(background: model.baseColor)
baseColBtn.addPropertyChangeListener("background",
{PropertyChangeEvent evt ->
model.baseColor = (Color) evt.getNewValue()
label.repaint() //need to figure out how to remove this call!!!
} as PropertyChangeListener)
[/groovy]

The Java code uses an anonymous inner class to kick off the process.

[java smarttabs=”true”]
new JButton(new AbstractAction("Start") {
public void actionPerformed(ActionEvent e) {
label.setBusy(!label.isBusy());
putValue(Action.NAME, label.isBusy() ? "Stop" : "Start");
}
})
[/java]

No anonymous inner classes in Groovy, and with the Griffon framework we can separate the concerns a bit better anyhow. This code is split up between the view and the controller classes. Note that the controller can reference(and update) the action by acting through its injected view component.

[groovy language=”true” smarttabs=”true”]
/* action and button defined in the view */
actions {
action(id: "startAction",
name: model.START_NAME,
mnemonic: "S",
accelerator: shortcut("S"),
closure: controller.start)
}
button(startAction)

/* controller action */
def start = { ActionEvent evt ->
view.label.setBusy(!view.label.isBusy())
view.startAction.putValue(Action.NAME, view.label.isBusy() ? "Stop" : "Start")
}
[/groovy]

Finally, here’s a code sample of how to add a listener to an existing component and bind the action to a method on the controller:

[groovy language=”true” smarttabs=”true”]
xSlider.addChangeListener(controller.&fcl as ChangeListener)
[/groovy]

In most cases, the sample code here is not trying very hard to shorten the syntax; there’s a lot of room for improvement and further Groovification. I’m sure there’s a better way to add listeners, for instance. Anyhow, aside from a few details, the application is up and running and doing the same thing as the original. Total effort expended: probably about 10 hours, a good portion of it spend Googling and reading. Next step is to write some tests to get better at that side of the equation. I’d be including more links about the excellent SwingX components in this post, but the SwingLabs website has been reporting “Maximum Connections Reached: 4096 — Retry later” all day. Hope everything gets fixed soon guys!

If you’re interested in seeing this demo live and in action, there’s a link to a short Jing video below.

Click here for video of the JXBusyLabel demo running on Griffon.

05 Apr, 2009

Twitter Weekly Updates for 2009-04-05

Posted by: TheKaptain In: TweetTweet

Powered by Twitter Tools.

Tags: ,

03 Apr, 2009

Griffon bash completion…

Posted by: TheKaptain In: Development

… means I don’t have to remember all of the available Griffon commands. My primary development platform is a Mac, so I used MacPorts to install the bash-completion package long ago.
This script is based entirely on the excellent maven completion script documented here on willcodeforbeer. It does the same job for Griffon and includes commands for the plugins I’m using.
[bash smarttabs=”true” language=”language=”]
# Griffon completion for the bash shell
#
_griffon()
{
local cmds cur colonprefixes
cmds="bootstrap clean compile console create-app \
create-fest-test create-integration-test create-mvc \
create-plugin create-script create-unit-test \
create-fest-test run-fest -cobertura help init \
install-plugin list-plugins package package-plugin \
plugin-info release-plugin run-app run-applet run-fest \
run-webstart set-proxy set-version shell stats test-app \
test-app-cobertura uninstall-plugin upgrade"
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
# Work-around bash_completion issue where bash interprets a colon
# as a separator.
# Work-around borrowed from the darcs work-around for the same
# issue.
colonprefixes=${cur%"${cur##*:}"}
COMPREPLY=( $(compgen -W ‘$cmds’ — $cur))
local i=${#COMPREPLY[*]}
while [ $((–i)) -ge 0 ]; do
COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"}
done

return 0
} &&
complete -F _griffon griffon
[/bash]

Add this to your .bash_profile file and you’re good to go for saving a whole bunch of keystrokes and calls to ‘griffon help’.

Reblog this post [with Zemanta]

03 Apr, 2009

SwingSet on Griffon

Posted by: TheKaptain In: Development

So as  as learning experience, I’ve decided to try cutting the  SwingSet demo application over to Groovy and Griffon. To make it a little more interesting, I’m going to base it off of the SwingX version.

The SwingX widgets have been a pleasure to work with in the past, and with the swingX plugin, it takes not a single line of extra code in order to use them.  The underlying SwingXBuilder provides factories which override the standard SwingBuilder syntax to replace the standard widget set with the SwingX equivalents. Simply add the prefix ‘jx’ to the standard SwingBuilder node calls and you’re in business.

Along the way I’m going to incorporate the fest and cobertura plugins to test out the UI. I’ve never used fest before but it seems that the only real requirement is to remember to give your components a uniquely identifiable id. There are additional ways of looking up components with fest, for sure, but unique ids should cover this application’s needs quite nicely. Using both together is a simple exercise on the command line.

[groovy]griffon run-fest -cobertura[/groovy]

Under the hood, Griffon uses TestNG, so the test class can also take advantage of some nice familiar annotations to assist configuration. Code coverage and testing results are provided by default in an html format, which anyone who likes their test coverage will be infinitely familiar with.  All in all, the experience of setup and execution of the testing framework is pretty painless.

The SwingSet demo is actually laid out pretty nicely for testing in the first place. There’ s a top level MainWindow class, which accepts a DemoPanel parameter. The full demo launches with a SwingXDemo subclass of DemoPanel that aggregates other subclasses of the same into a tabbed pane. Tests are free to call the MainWindow class with any of the individual panels as a parameter, so testing them on their own using fest looks like it would be a cinch.  In Griffon terms this roughly translates to a root MVC group that composes another MVC group that is specified by id. Easier to show than to explain, with an example of a call that would go in the controller:

[groovy]
createMVCGroup(mvcGroupIDParam, uid, [… param map …] )
[/groovy]

The first thing created in the SwingSet UI is the menu, so that’s what I created first as well. In the view class:

[groovy language=”true” smarttabs=”true”]
actions {
action(id: "quitAction",
name: model.QUIT_NAME,
mnemonic: "Q",
accelerator: shortcut("Q"),
closure: controller.quit)
}

menuBar {
menu(model.MENU_NAME) {
menuItem(name: model.QUIT_NAME, action:quitAction)
}
}
[/groovy]

The component names are defined in the model class so that they can easily be extracted later for testing purposes.
Including the fest plugin with Griffon adds a target which is used to create a new test, which will prompt you for a test name.
[groovy]create-fest-test[/groovy]

The new test class is created with all of the necessary code to let fest launch the base application frame. This first test is very simple, just making sure that our single menu item is present in the GUI.
[groovy language=”true” smarttabs=”true”]
@Test
void testQuitMenuItemPresent()
{
Assert.assertNotNull( window.menuItem(GriffonSwingSet3Model.QUIT_NAME) )
}
[/groovy]

That’s really all it takes to launch a new application using the test harness and verify UI component state. Man, can I think of a couple of times in the past where that might have come in handy 🙂

Next, step is cutting over the first SwingSet DemoPanel, a demonstration of JXBusyLabel – 635 lines of the usual Swing inner classes and boilerplate GridBagLayout constraints code. Really looking forward to seeing how it looks in Groovy.

Reblog this post [with Zemanta]

01 Apr, 2009

The first two chapters of Griffon In Action

Posted by: TheKaptain In: Development

Documentation up until now has been sparse to be sure, but judging by the first two chapters of the MEAP for Griffon in Action, this book is going to be worth every penny.

I’ve experimented a bit with Griffon a bit lately, but still being somewhat of a Groovy noob, I don’t think that the full impact hit me until I started reading the book. Maybe part of the problem is not that it’s hard to understand, but that it’s hard to believe that it’s so easy.

A very clearly defined way of separating the classic MVC. Injection of views, models, controllers – all available by convention not by annotation, xml configuration or even having to a refer to a component by name. The transparent access to a variety of builder actions through plugins makes a large toolset available with little or no cost. Clear architectural boundaries exist that guide you to where your code should be developed. The Griffon framework, created with gracious acknowledgement to its forerunner Grails strives to do one thing above all – make Swing easy.

The power and versatility of Swing has always been obvious to me. The ‘magic sauce’ that makes large scale Java Swing applications behave in any sane way has been a little more hazy. The advent of SwingWorker and other enhancements to the Swing toolset and the availability of better documentation have certainly made the landscape a lot more tolerable, but at the end of the day, it’s still hard to even find good examples of large Swing apps to use as a guideline(well at least it has been for me.) On the other side of the spectrum, I’m not sure there IS such a thing as a small Swing app. The amount of boilerplate code required is cumbersame, to say the least, and between anonymous inner classes for actions/listeners and correct handling of business logic and the EDT by the time you’ve finished doing anything moderately significant you’re already a couple 1000 lines in.

Griffon takes all that and hides it behind a curtain. Expanding on the already powerful SwingBuilder capabilities, it provides a quick and easy way to develop complex Swing applications. Utilizing @Binding to provide easy view/model interaction and baking the Observer pattern right into the framework make it beyond simple to deal with GUI events. And the pattern for dealing with EDT issues couldn’t be much more straightforward.

[groovy]

doOutside {
…. do whatever you need to do off of the EDT
doLater { … come back to the EDT when you’re done to update widgets }
}

[/groovy]

I’m pretty sure that’s an easy enough pattern that I will never again forget the cost of doing… well pretty much anything that takes +1 second while blocking the EDT.

Personally, I’ve run into a couple of unexpected results when trying to utilize the webstart version of the application, but other than that everything has worked exactly as advertised. And at the end of the day I’m willing to chalk that up to my misuse of the system. I’ll tell you for sure when I get to that chapter of the book. Which will probably be about 2 days after the authors publish it.

🙂

So far my impression of the pre-release chapters of the book are pretty good – well written, clear and above all – the code samples work. Kudos to the authors Andres Almiray, Danno Ferrin and Geertjan Wielenga.  Look forward to the rest of the book boys, and to writing some new Swing apps with Griffon!

Reblog this post [with Zemanta]

31 Mar, 2009

WordPress app for the iPhone comes through!

Posted by: TheKaptain In: Cool Toys

I blogged awhile back about the WordPress iPhone app, and how the tiny portrait keyboard was just killing me. Well they’ve gone ahead and added a landscape mode and it is just GREAT! I look forward to drafting posts on it when the inspiration strikes.
A couple of minor hiccups, however.

Upgrading the previous install caused the app to crash every time after a second or two. A quick reinstall fixed the problem, and really it is a small price to pay for free software.

There also appears to be an issue or two with a disappearing save button. And the first time I entered this post, it apparently got lost in translation becuase although the new post showed up in WordPress, the title was the only thing populated.  Oh, well – the button problem is already in bug tracking and if I REALLY wanted, I could just fix it myself since it’s open source and available for download. Aaaah, if only I had the time to learn how to be an iPhone developer right now – maybe next month.

In the meantime I’m just going to say a bit thank you to the developers of the application and use it as much as possible. Don’t worry guys – I promise to file bug reports

In other news, I’m looking forward to the new Griffon In Action book coming out – but that’s another blog post.

Reblog this post [with Zemanta]