griffon @ svwjug

39
Welcome to the Desktop Revolution

Upload: andres-almiray

Post on 28-Jan-2015

111 views

Category:

Technology


0 download

DESCRIPTION

A Griffon talk presented @ SV web JUG on July 21st 09

TRANSCRIPT

Page 1: Griffon @ Svwjug

Welcome to the Desktop Revolution

Page 2: Griffon @ Svwjug

What is Griffon ?

Page 3: Griffon @ Svwjug
Page 4: Griffon @ Svwjug

+ +

+ Sugar, Spice and everything Nice =

Page 5: Griffon @ Svwjug
Page 6: Griffon @ Svwjug

HelloWorld.java

public class HelloWorld { String name;

public void setName(String name) { this.name = name; } public String getName(){ return name; }

public String greet() { return "Hello "+ name; }

public static void main(String args[]){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.err.println( helloWorld.greet() ); }}

Page 7: Griffon @ Svwjug

HelloWorld.groovy

public class HelloWorld { String name;

public void setName(String name) { this.name = name; } public String getName(){ return name; }

public String greet() { return "Hello "+ name; }

public static void main(String args[]){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.err.println( helloWorld.greet() ); }}

Page 8: Griffon @ Svwjug

GroovierHelloWorld.groovy

class HelloWorld { String name def greet() { "Hello $name" }}

def helloWorld = new HelloWorld(name:"Groovy")println helloWorld.greet()

Page 9: Griffon @ Svwjug
Page 10: Griffon @ Svwjug

Swing

Page 11: Griffon @ Svwjug

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); } }); } // next page ...

Page 12: Griffon @ Svwjug

// continued ... 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; }}

Page 13: Griffon @ Svwjug

●The light at the end of the tunnel...

Page 14: Griffon @ Svwjug

import groovy.swing.SwingBuilderimport 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) }}

Page 15: Griffon @ Svwjug

What is going on?

Each node is syntactically a method call

All of these method calls are dynamically dispatched

Most don’t actually exist in bytecode

Child closures create hierarchical relations

Child widgets are added to parent containers

SwingBuilder node names are derived from Swing classes

Remove the leading ‘J’ from a Swing class when present

SwingBuilder also supports some AWT classes like layouts

Page 16: Griffon @ Svwjug

●Threads

Page 17: Griffon @ Svwjug

Threading and the EDT

All painting and UI operations must be done in the EDT

Anything else should be outside the EDT

Swing has SwingUtilities using Runnable

Java 6 technology adds SwingWorker

However, closures are Groovy

For code inside EDT

edt { … }doLater { … }

For code outside EDT

doOutside { … }Build UI on the EDT

SwingBuilder.build { … }

Page 18: Griffon @ Svwjug

Threading Example

action( id: 'countdown', name: 'Start Countdown', closure: { evt -> int count = lengthSlider.value status.text = count while ( --count >= 0 ) { sleep( 1000 ) status.text = count } status.background = Color.RED })

Page 19: Griffon @ Svwjug

Threading Example

action( id: 'countdown', name: 'Start Countdown', closure: { evt -> int count = lengthSlider.value status.text = count doOutside { while ( --count >= 0 ) { sleep( 1000 ) edt { status.text = count } } doLater { status.background = Color.RED } }})

Page 20: Griffon @ Svwjug

Binding

Page 21: Griffon @ Svwjug

Binding Example

import groovy.swing.SwingBuilder

new SwingBuilder().edt { frame( title: "Binding Test", size: [200, 120], visible: true ) { gridLayout( cols: 1, rows: 2 ) textField( id: "t1" ) textField( id: "t2", editable: false ) } bind(source: t1, sourceProperty: "text", target: t2, targetProperty: "text")}

Page 22: Griffon @ Svwjug

Binding Example

import groovy.swing.SwingBuilder

new SwingBuilder().edt { frame( title: "Binding Test", size: [200, 120], visible: true ) { gridLayout( cols: 1, rows: 2 ) textField( id: "t1" ) textField( id: "t2", editable: false, text: bind(source: t1, sourceProperty: "text") ) }}

Page 23: Griffon @ Svwjug

Binding Example

import groovy.swing.SwingBuilder

new SwingBuilder().edt { frame( title: "Binding Test", size: [200, 120], visible: true ) { gridLayout( cols: 1, rows: 2 ) textField( id: "t1" ) textField( id: "t2", editable: false, text: bind{ t1.text } ) }}

Page 24: Griffon @ Svwjug
Page 25: Griffon @ Svwjug

Convention over Configuration

Don't repeat yourself (DRY)

MVC Pattern

Testing supported “out of the box”

Automate repetitive tasks

Page 26: Griffon @ Svwjug

Convention over Configuration

Java Desktop Application Conventions are MIA

Very few official examples

No Blueprints (Like Java EE Blueprints)

We have to create our own

Following Grails Patterns

Source Files Segregated by Role

Standardize App Lifecycle (like JSR-296)

Automated Packaging (App, WebStart, Applet)

Page 27: Griffon @ Svwjug
Page 28: Griffon @ Svwjug

Lyfecycle Scripts

Lifecycle Scripts are in griffon-app/lifecycle

Lifecycle Events modeled after JSR-296

Initialize

Startup

Ready

Shutdown

Page 29: Griffon @ Svwjug

Don't Repeat Yourself

How? Use a Dynamic Language!

With Closures/Blocks

With terse property syntaxmyJTextArea.text = "Fires Property Change"

With terse eventing syntaxbutton.actionPerformed = {println 'hi'}

With Rich Annotation Support@Bindable String aBoundProperty

Most of this impacts the View Layer

See JavaOne 2008 TS-5098 - Building Rich Applications with Groovy's SwingBuilder

Page 30: Griffon @ Svwjug

Built-in Testing

Griffon has built in support for testing

create-mvc script creates a test file in test/integration

Uses GroovyTestCase

See JavaOne 2008 TS-5101 – Boosting your Testing Productivity with Groovy

Griffon doesn’t write the test for you

test-app script executes the tests for youBootstraps the application for you

Everything up to instantiating MVC Groups

Page 31: Griffon @ Svwjug

Testing Plugins

Sometimes apps need more involved testing

fest Fluent interface for functional swing testing

easybBehavioral Driven Development

code-coverage – CoberturaLine Coverage Metrics

jdependCode quality metrics

codenarcStatic code analysis

Page 32: Griffon @ Svwjug

Automate Tasks

command line interface

Scripts and events

plugins

builders: SwingX, JIDE, Flamingo, Trident , CSS, JavaFX and more

miscellaneous: installer (IzPack, RPM, OSX app bundles), Splash, Wizard, Scala

Page 33: Griffon @ Svwjug

●Griffon's Roadmap

Page 34: Griffon @ Svwjug

Resources

http://griffon.codehaus.org

http://griffon.codehaus.org/Builders

http://griffon.codehaus.org/Plugins

http://groovy.dzone.com

twitter: @theaviary

Page 35: Griffon @ Svwjug

Griffon in Action (2010)

● http://manning.com/almiray

Page 36: Griffon @ Svwjug

● http://groovymag.com

Groovy, Grails, Griffon and more!

Page 37: Griffon @ Svwjug

Questions

Page 38: Griffon @ Svwjug

●Thank you!

Page 39: Griffon @ Svwjug

Image Credits

http://www.flickr.com/photos/fadderuri/841064754/

http://www.flickr.com/photos/colorloose/3539708679/

http://www.flickr.com/photos/icultist/2842153495/

http://www.flickr.com/photos/bishi/2313888267/

http://www.flickr.com/photos/kirimobile/2581287574/

http://www.flickr.com/photos/chelseaaaaaa/3564365301/

http://www.flickr.com/photos/psd/2086641/