Friday, January 19, 2007

Groovy and SwingBuilder

In my comparison of IronPython, Groovy and JRuby I used a "naked" Swing API to create a GUI application using Groovy. Groovy comes with a nice library called SwingBuilder that simplifies a lot of work with Swing. I couldn't find any documentation for SwingBuilder but the source code is pretty straight-forward. In my opinion, the best thing in the SwingBuilder version is the way you declare that a form has a button:

def frame = swing.frame(defaultCloseOperation: WC.EXIT_ON_CLOSE) {
button('OK', actionPerformed: click)
}

You can pass a closure to the frame method.
I really like this way. It allows you to create your GUI in a more declarative way.

As was suggested by Martin C. Martin and Dierk Koenig (many thanks!) on the Groovy-user list, the code might look something like the following:

import javax.swing.WindowConstants as WC

click = { event ->
event.source.text = "Pressed!"
}

def swing = new groovy.swing.SwingBuilder()
def frame = swing.frame(
size: [200, 200],
defaultCloseOperation: WC.EXIT_ON_CLOSE,
title: 'Hello' ) {
button('OK', actionPerformed: click)
}

frame.show()

Thursday, January 11, 2007

Iron Python on Balloons

Have you ever wondered how to create a simple application that uses balloons to notify about some events? Below is the result of my spike on how I could use IronPython and Windows Forms to create such thing.



Basically, it should:

  1. show an icon in the system tray

  2. NotifyIcon is a class that allows you to display an icon in the system tray.

  3. display a tooltip every n milliseconds

  4. It was easily achieved by using the notifyIcon.ShowBalloonTip method and the Timer (and its Tick event) class.

  5. have a context menu that allows you to exit the application

  6. The ContextMenu class.


Just paste the code to the Main.py file, prepare a test.ico file and run it with:
ipy Main.py

import clr

clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Drawing import Icon
from System.Windows.Forms import (Application, ContextMenu,
MenuItem, NotifyIcon, Timer)


class Main(object):

def __init__(self):
self.initNotifyIcon()
timer = Timer()
timer.Interval = 60000
timer.Tick += self.onTick
timer.Start()


def initNotifyIcon(self):
self.notifyIcon = NotifyIcon()
self.notifyIcon.Icon = Icon("test.ico")
self.notifyIcon.Visible = True
self.notifyIcon.ContextMenu = self.initContextMenu()


def onTick(self, sender, event):
self.notifyIcon.BalloonTipTitle = "Hello, I'm IronPython"
self.notifyIcon.BalloonTipText = "Who are you?"
self.notifyIcon.ShowBalloonTip(1000)


def initContextMenu(self):
contextMenu = ContextMenu()
exitMenuItem = MenuItem("Exit")
exitMenuItem.Click += self.onExit
contextMenu.MenuItems.Add(exitMenuItem)
return contextMenu


def onExit(self, sender, event):
self.notifyIcon.Visible = False
Application.Exit()


if __name__ == "__main__":
main = Main()
Application.Run()

Update:Marcin shows how to achieve the same with Groovy.