Porting legacy apps to Griffon

39
Porting your legacy apps to Griffon James Williams @ecspike Software Engineer, BT/Ribbit

description

Presented on April 16, 2010 at GR8 USA.

Transcript of Porting legacy apps to Griffon

Page 1: Porting legacy apps to Griffon

Porting your legacy apps to Griffon

James Williams@ecspike

Software Engineer, BT/Ribbit

Page 2: Porting legacy apps to Griffon

Goals•The basics of Griffon•Griffon tenets•Respect the EDT's authority•SwingWorker is your friend•Embrace simpler layout managers•MVC does a codebase good•Go modular•Deploy, deploy, deploy!

Page 3: Porting legacy apps to Griffon

What is Griffon?•desktop framework •inspired by Grails and the SAF•leverages Swing and Groovy•Apache 2 Licensed•extensible with plugins and addons

Page 4: Porting legacy apps to Griffon

Griffon Tenets•Convention over Configuration•Don't Repeat Yourself•Pervasive MVC•Use Data Binding•Write Good Tests•Automate Tasks

Page 5: Porting legacy apps to Griffon

Convention over Configuration

Page 6: Porting legacy apps to Griffon

Griffon application structure

Page 7: Porting legacy apps to Griffon

Core commands•griffon create-app•griffon run-app•griffon run-applet•griffon run-webstart•griffon package•griffon list-plugins•griffon install-plugin

Page 8: Porting legacy apps to Griffon

Don't Repeat Yourself

Page 9: Porting legacy apps to Griffon

Would you prefer this ...public class JavaFrame extends JFrame { public JavaFrame { setLayout(new GridLayout(3,1)); setTitle("JavaFrame"); setSize(100,100); add(new JLabel("One")); add(new JLabel("Two")); add(new JLabel("Three")); } public static void main(String [] args) { new JavaFrame().setVisible(true); }}

Page 10: Porting legacy apps to Griffon

... or this?def swing = new SwingBuilder()

swing.frame(size:[100,100], title:'JavaFrame', layout:new GridLayout(3,1)) { label('One') label('Two') label('Three')}.show()

Page 11: Porting legacy apps to Griffon

Griffon Builders•DSLs for UI components•allows nesting•takes parameters as a HashMap•can be mixed and matched

Page 12: Porting legacy apps to Griffon

Supported UI toolkits•Swing/X•JIDE•MacWidgetsBuilder•Flamingo•SwingXtras•JavaFX

Page 13: Porting legacy apps to Griffon

Respect the EDT

Page 14: Porting legacy apps to Griffon

Respect the EDT•Event Dispatching thread•the cause of 94% of speed problems*

•only UI updates should run on it*•first-in/first out•Griffon EDT helpers•edt•doOutside/Later/Inside•withWorker

Page 15: Porting legacy apps to Griffon

Swingworker•designed for long tasks•can periodically update the UI or notify processes outside the worker

•Swing Worker closures:•onInit•work•publish•onUpdate•onDone

Page 16: Porting legacy apps to Griffon

Embrace simpler layout managers

Page 17: Porting legacy apps to Griffon

What's the result of having to tweak the UI of a NB Matisse layout?

Page 18: Porting legacy apps to Griffon

Pain.

Page 19: Porting legacy apps to Griffon

MigLayout•row-column based layout manager•can replace most layout managers•uses constraints for positioning•can do relative positioning

Page 20: Porting legacy apps to Griffon

MigLayoutimport net.miginfocom.swing.MigLayout application(title:'Griffon Weather', pack:true, size:[700,400], pack:true, locationByPlatform:true, layout:new MigLayout()) { label("Airport Code:") textField(id:'tf',columns:5, constraints:'spanx', actionPerformed: { controller.getJSON( 'http://ws.geonames.org/weatherIcaoJSON?ICAO=K'+tf.text?.toUpperCase()) } )

def createHorizontalBox = { fieldName, boundParam -> label(fieldName, constraints:"newline") label(id:fieldName.replace(' ','_')+'Label', foreground: java.awt.Color.BLUE, text: bind(source:model, sourceProperty:boundParam), constraints:'wrap' ) }

def createHorizontalBoxWithSuffix = { fieldName, boundParam, suffix -> label(fieldName, constraints:'newline') label(id:fieldName.replace(' ','_')+'Label', foreground: java.awt.Color.BLUE, text: bind(source:model, sourceProperty:boundParam, converter:{it + suffix}), constraints:"wrap, spanx") }

createHorizontalBox('Station: ', "stationName") createHorizontalBox('Clouds: ', "clouds") createHorizontalBoxWithSuffix('Wind Direction: ', "windDirection", " degrees") //truncated for brevity}

Page 21: Porting legacy apps to Griffon

MigLayout

Page 22: Porting legacy apps to Griffon

Pervasive MVC

Page 23: Porting legacy apps to Griffon

MVC•Models•store data for the MVC Group•can mark properties as @Bindable

•Views•represent a single UI in your app•can be written in Groovy OR Java

•Controllers•the brains of the group

Page 24: Porting legacy apps to Griffon

A sample modelimport groovy.beans.Bindable

class SampleModel { @Bindable String name def age def location}

Page 25: Porting legacy apps to Griffon

A sample viewapplication(title:'Sample App', size:[320,480]){ label('Content goes here')}

Page 26: Porting legacy apps to Griffon

A sample controllerclass SampleController { //injected by Griffon def model def view

void mvcGroupInit(Map args) { }

/* def action = {evt = null -> } */

Page 27: Porting legacy apps to Griffon

Use Data Binding

Page 28: Porting legacy apps to Griffon

Binding•automagically wraps properties•reduce the amount of code to update UIs•can move data in one or both directions

Page 29: Porting legacy apps to Griffon

Binding exampleslabel(text:bind{model.name})label(text: bind(source:model, sourceProperty:'name'))textField(text: bind(target:model, targetProperty:'name'))

textField(text:bind(source:model, sourceProperty:'name', mutual:true))

Page 30: Porting legacy apps to Griffon

MVC/Binding Demos

Page 31: Porting legacy apps to Griffon

Write Good Tests

Page 32: Porting legacy apps to Griffon

I should be I usually don't. :(

Page 33: Porting legacy apps to Griffon

Automate Tasks

Page 34: Porting legacy apps to Griffon

Go Modular

Page 35: Porting legacy apps to Griffon

Modularity•plugins - compile-time extensions•addons - runtime extensions•~ 50 plugins/addons availiable•UI frameworks•Database•Testing frameworks•Other JVM languages

Page 36: Porting legacy apps to Griffon

Deploy, Deploy, Deploy!

Page 37: Porting legacy apps to Griffon

Deployment•Deploy to applet, webstart, or desktop with no code changes*•Installer plugin for OS specific pkgs

Page 38: Porting legacy apps to Griffon

What if you can't move to Griffon?

•JavaBuilders•http://code.google.com/p/javabuilders

•Guts-Gui•http://kenai.com/projects/guts

•Netbeans Platform•http://platform.netbeans.org/

Page 39: Porting legacy apps to Griffon

LinksBlog: http://jameswilliams.be/blogTwitter: @ecspikeGriffon: http://griffon.codehaus.org