SlideShare a Scribd company logo
Griffon
Groovy-er desktop applications



                    © 2011 Eric Wendelin
Griffon
Building desktop apps for the JVM just
             got Groovy
import   java.awt.GridLayout;
import   java.awt.event.ActionListener;
import   java.awt.event.ActionEvent;
import   javax.swing.JFrame;
import   javax.swing.JTextField;
import   javax.swing.JButton;
import   javax.swing.SwingUtilities;

public class JavaFrame {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
             public void run() {	
                 JFrame frame = buildUI();
             }
             frame.setVisible(true);
        });
    }
    private static JFrame buildUI() {
        JFrame frame = new Jframe("JavaFrame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(3,1));
        final JTextField input = new JTextField(20);
        final JTextField output = new JTextField(20);
        output.setEditable(false); JButton button = new JButton("Click me!");
        button.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent event) {
	                output.setText(input.getText());
	           }
        });
        frame.getContentPane().add(input);
        frame.getContentPane().add(button);
        frame.getContentPane().add(output);
        frame.pack();
        return frame;
    }
  }
import groovy.swing.SwingBuilder
import static javax.swing.JFrame.EXIT_ON_CLOSE
new SwingBuilder().edt {
    frame(title: "GroovyFrame", pack: true, visible: true,
            defaultCloseOperation: EXIT_ON_CLOSE) {
        gridLayout(cols: 1, rows: 3)
        textField(id: "input", columns: 20)
        button("Click me!", actionPerformed: {
            output.text = input.text
        })
        textField(id: "output", columns: 20, editable: false)
    }
}
Based on
Ow! Pointy!


Convention
             >
              Configuration
MVC
griffon create-mvc Login
@Bindable
BOOM! Built in!



        griffon test-app
Lots of deployment
      options
     griffon package jar
application(title: ‘GroovyTitle’, pack: true) {
    gridLayout(cols: 1, rows: 3)
    textField(id: "input", columns: 20)
    button("Click me!", actionPerformed: {
        output.text = input.text
    })
    textField(id: "output", columns: 20, editable: false)
}
Plugins and Addons!
   griffon install-plugin easyb
Polyglot
griffon install-plugin jython
Multi-UI Toolkit
   Support
You should
probably buy me!
Thanks!
          also go here

griffon.codehaus.org

                 @eriwen
Groovy-er desktop applications with Griffon

More Related Content

Similar to Groovy-er desktop applications with Griffon

Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
Write a GUI application to simulate writing out a check. The value o.pdf
Write a GUI application to simulate writing out a check. The value o.pdfWrite a GUI application to simulate writing out a check. The value o.pdf
Write a GUI application to simulate writing out a check. The value o.pdf
fathimaoptical
 
In Java Write a GUI application to simulate writing out a check. The.pdf
In Java Write a GUI application to simulate writing out a check. The.pdfIn Java Write a GUI application to simulate writing out a check. The.pdf
In Java Write a GUI application to simulate writing out a check. The.pdf
flashfashioncasualwe
 
Tuto jtatoo
Tuto jtatooTuto jtatoo
correct the error and add code same in the pic import jav.pdf
correct the error and add code same in the pic   import jav.pdfcorrect the error and add code same in the pic   import jav.pdf
correct the error and add code same in the pic import jav.pdf
devangmittal4
 
correct the error import javaxswingJFrame import javaxs.pdf
correct the error import javaxswingJFrame import javaxs.pdfcorrect the error import javaxswingJFrame import javaxs.pdf
correct the error import javaxswingJFrame import javaxs.pdf
devangmittal4
 
I am getting a syntax error. I cant seem to find whats causing t.pdf
I am getting a syntax error. I cant seem to find whats causing t.pdfI am getting a syntax error. I cant seem to find whats causing t.pdf
I am getting a syntax error. I cant seem to find whats causing t.pdf
fashionfolionr
 
Getting started with GUI programming in Java_1
Getting started with GUI programming in Java_1Getting started with GUI programming in Java_1
Getting started with GUI programming in Java_1Muhammad Shebl Farag
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
sudhirchourasia86
 
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdfimport java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
venkt12345
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
package buttongui; import static com.sun.deploy.config.JREInf.pdf
package buttongui; import static com.sun.deploy.config.JREInf.pdfpackage buttongui; import static com.sun.deploy.config.JREInf.pdf
package buttongui; import static com.sun.deploy.config.JREInf.pdf
arjuntiwari586
 
SWTBot Tutorial
SWTBot TutorialSWTBot Tutorial
SWTBot Tutorial
Chris Aniszczyk
 
Griffon不定期便〜G*ワークショップ編〜
Griffon不定期便〜G*ワークショップ編〜Griffon不定期便〜G*ワークショップ編〜
Griffon不定期便〜G*ワークショップ編〜Kiyotaka Oku
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
Thierry Wasylczenko
 
Vaadin7
Vaadin7Vaadin7
Unit-2 swing and mvc architecture
Unit-2 swing and mvc architectureUnit-2 swing and mvc architecture
Unit-2 swing and mvc architecture
Amol Gaikwad
 
What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.
Mark Rees
 

Similar to Groovy-er desktop applications with Griffon (20)

Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Write a GUI application to simulate writing out a check. The value o.pdf
Write a GUI application to simulate writing out a check. The value o.pdfWrite a GUI application to simulate writing out a check. The value o.pdf
Write a GUI application to simulate writing out a check. The value o.pdf
 
In Java Write a GUI application to simulate writing out a check. The.pdf
In Java Write a GUI application to simulate writing out a check. The.pdfIn Java Write a GUI application to simulate writing out a check. The.pdf
In Java Write a GUI application to simulate writing out a check. The.pdf
 
Tuto jtatoo
Tuto jtatooTuto jtatoo
Tuto jtatoo
 
correct the error and add code same in the pic import jav.pdf
correct the error and add code same in the pic   import jav.pdfcorrect the error and add code same in the pic   import jav.pdf
correct the error and add code same in the pic import jav.pdf
 
correct the error import javaxswingJFrame import javaxs.pdf
correct the error import javaxswingJFrame import javaxs.pdfcorrect the error import javaxswingJFrame import javaxs.pdf
correct the error import javaxswingJFrame import javaxs.pdf
 
I am getting a syntax error. I cant seem to find whats causing t.pdf
I am getting a syntax error. I cant seem to find whats causing t.pdfI am getting a syntax error. I cant seem to find whats causing t.pdf
I am getting a syntax error. I cant seem to find whats causing t.pdf
 
GUI Programming with Java
GUI Programming with JavaGUI Programming with Java
GUI Programming with Java
 
Getting started with GUI programming in Java_1
Getting started with GUI programming in Java_1Getting started with GUI programming in Java_1
Getting started with GUI programming in Java_1
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
 
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdfimport java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
package buttongui; import static com.sun.deploy.config.JREInf.pdf
package buttongui; import static com.sun.deploy.config.JREInf.pdfpackage buttongui; import static com.sun.deploy.config.JREInf.pdf
package buttongui; import static com.sun.deploy.config.JREInf.pdf
 
CORE JAVA-2
CORE JAVA-2CORE JAVA-2
CORE JAVA-2
 
SWTBot Tutorial
SWTBot TutorialSWTBot Tutorial
SWTBot Tutorial
 
Griffon不定期便〜G*ワークショップ編〜
Griffon不定期便〜G*ワークショップ編〜Griffon不定期便〜G*ワークショップ編〜
Griffon不定期便〜G*ワークショップ編〜
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Unit-2 swing and mvc architecture
Unit-2 swing and mvc architectureUnit-2 swing and mvc architecture
Unit-2 swing and mvc architecture
 
What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.
 

Recently uploaded

Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 

Recently uploaded (20)

Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 

Groovy-er desktop applications with Griffon

  • 2. Griffon Building desktop apps for the JVM just got Groovy
  • 3.
  • 4.
  • 5. import java.awt.GridLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JButton; import javax.swing.SwingUtilities; public class JavaFrame { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable(){ public void run() { JFrame frame = buildUI(); } frame.setVisible(true); }); } private static JFrame buildUI() { JFrame frame = new Jframe("JavaFrame"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setLayout(new GridLayout(3,1)); final JTextField input = new JTextField(20); final JTextField output = new JTextField(20); output.setEditable(false); JButton button = new JButton("Click me!"); button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event) { output.setText(input.getText()); } }); frame.getContentPane().add(input); frame.getContentPane().add(button); frame.getContentPane().add(output); frame.pack(); return frame; } }
  • 6.
  • 7.
  • 8. import groovy.swing.SwingBuilder import static javax.swing.JFrame.EXIT_ON_CLOSE new SwingBuilder().edt { frame(title: "GroovyFrame", pack: true, visible: true, defaultCloseOperation: EXIT_ON_CLOSE) { gridLayout(cols: 1, rows: 3) textField(id: "input", columns: 20) button("Click me!", actionPerformed: { output.text = input.text }) textField(id: "output", columns: 20, editable: false) } }
  • 9.
  • 11. Ow! Pointy! Convention > Configuration
  • 14. BOOM! Built in! griffon test-app
  • 15. Lots of deployment options griffon package jar
  • 16. application(title: ‘GroovyTitle’, pack: true) { gridLayout(cols: 1, rows: 3) textField(id: "input", columns: 20) button("Click me!", actionPerformed: { output.text = input.text }) textField(id: "output", columns: 20, editable: false) }
  • 17. Plugins and Addons! griffon install-plugin easyb
  • 19. Multi-UI Toolkit Support
  • 21. Thanks! also go here griffon.codehaus.org @eriwen