Porting legacy apps to Griffon


Published on

Presented on April 16, 2010 at GR8 USA.

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Porting legacy apps to Griffon

  1. 1. Porting your legacy apps to Griffon James Williams @ecspike Software Engineer, BT/Ribbit
  2. 2. 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!
  3. 3. What is Griffon? •desktop framework •inspired by Grails and the SAF •leverages Swing and Groovy •Apache 2 Licensed •extensible with plugins and addons
  4. 4. Griffon Tenets •Convention over Configuration •Don't Repeat Yourself •Pervasive MVC •Use Data Binding •Write Good Tests •Automate Tasks
  5. 5. Convention over Configuration
  6. 6. Griffon application structure
  7. 7. Core commands •griffon create-app •griffon run-app •griffon run-applet •griffon run-webstart •griffon package •griffon list-plugins •griffon install-plugin
  8. 8. Don't Repeat Yourself
  9. 9. 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); } }
  10. 10. ... 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()
  11. 11. Griffon Builders •DSLs for UI components •allows nesting •takes parameters as a HashMap •can be mixed and matched
  12. 12. Supported UI toolkits •Swing/X •JIDE •MacWidgetsBuilder •Flamingo •SwingXtras •JavaFX
  13. 13. Respect the EDT
  14. 14. 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
  15. 15. Swingworker •designed for long tasks •can periodically update the UI or notify processes outside the worker •Swing Worker closures: •onInit •work •publish •onUpdate •onDone
  16. 16. Embrace simpler layout managers
  17. 17. What's the result of having to tweak the UI of a NB Matisse layout?
  18. 18. Pain.
  19. 19. MigLayout •row-column based layout manager •can replace most layout managers •uses constraints for positioning •can do relative positioning
  20. 20. MigLayout import 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 }
  21. 21. MigLayout
  22. 22. Pervasive MVC
  23. 23. 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
  24. 24. A sample model import groovy.beans.Bindable class SampleModel { @Bindable String name def age def location }
  25. 25. A sample view application(title:'Sample App', size:[320,480]){ label('Content goes here') }
  26. 26. A sample controller class SampleController { //injected by Griffon def model def view void mvcGroupInit(Map args) { } /* def action = {evt = null ->
  27. 27. Use Data Binding
  28. 28. Binding •automagically wraps properties •reduce the amount of code to update UIs •can move data in one or both directions
  29. 29. Binding examples label(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))
  30. 30. MVC/Binding Demos
  31. 31. Write Good Tests
  32. 32. I should be I usually don't. :(
  33. 33. Automate Tasks
  34. 34. Go Modular
  35. 35. Modularity •plugins - compile-time extensions •addons - runtime extensions •~ 50 plugins/addons availiable •UI frameworks •Database •Testing frameworks •Other JVM languages
  36. 36. Deploy, Deploy, Deploy!
  37. 37. Deployment •Deploy to applet, webstart, or desktop with no code changes* •Installer plugin for OS specific pkgs
  38. 38. 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/
  39. 39. Links Blog: http://jameswilliams.be/blog Twitter: @ecspike Griffon: http://griffon.codehaus.org