GR8Conf 2009: Griffon by Jim Shingler
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

GR8Conf 2009: Griffon by Jim Shingler

on

  • 3,133 views

Jim Shingler presents an introduction to the Griffon Swing MVC framework.

Jim Shingler presents an introduction to the Griffon Swing MVC framework.

Statistics

Views

Total Views
3,133
Views on SlideShare
2,593
Embed Views
540

Actions

Likes
2
Downloads
81
Comments
0

5 Embeds 540

http://grails.org.mx 469
http://www.grails.org.mx 60
http://www.slideshare.net 8
http://grails.org.mx:8080 2
http://translate.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

GR8Conf 2009: Griffon by Jim Shingler Presentation Transcript

  • 1. Introduction to Creating a Griffon: Rich Client front-end to our Twitter Clone By Jim Shingler © Jim Shingler Wednesday, May 13, 2009 1
  • 2. Abstract Groovy and Grails have given us the ability to leverage the strength of the Java Platform (and Eco System) and the productivity of “Convention over Configuration” to construct websites. But “What If” the User Interface requirements of the new application is best solved with the type of interaction a desktop application provides? Griffon bring the same productivity gains to the desktop application that Grails brings to web applications. This session will use Griffon and popular open source libraries to build a desktop application to interact with a Grails backend. © Jim Shingler Wednesday, May 13, 2009 2
  • 3. Introduction My name is Jim Shingler Chief Technical Architect President of Genuine Solutions Beginning Groovy and Grails Co-Author FallME (Inversion of Control for JavaME) Co-Founder Griffon Splash Plugin Author Griffon gConfig Author Griffon TM Bundle Author © Jim Shingler Wednesday, May 13, 2009 3
  • 4. Agenda Griffon 101 •What is Griffon •Installing Griffon •0 -100 k/mph in 60 seconds </xml> •Plugins Overview •Teaching the Griffon to count (Binding and Threading) •Readying Graeme’s Twitter Clone Griffon 201 •Griffon Twitter Client © Jim Shingler Wednesday, May 13, 2009 4
  • 5. Installing Griffon 1. Download Griffon 2. Unpack it (unix: /opt/local/share/ windows: /apps/griffon) 3. Set the GROOVY_HOME 4. Add it to your path, <GROOVY_HOME>/bin © Jim Shingler Wednesday, May 13, 2009 5
  • 6. 0-100 k/mph in 60 Seconds > griffon create-app small Welcome to Griffon 0.1.0 - http://griffon.codehaus.org/ Licensed under Apache Standard License 2.0 Griffon home is set to: /opt/local/share/griffon-0.1.0 ... > griffon run-app © Jim Shingler Wednesday, May 13, 2009 6
  • 7. DEMO © Jim Shingler Wednesday, May 13, 2009 7
  • 8. Congratulations you are a Developer © Jim Shingler Wednesday, May 13, 2009 8
  • 9. Don’t forget to update your resume. Griffon © Jim Shingler Wednesday, May 13, 2009 9
  • 10. App Structure & Convention A pretty standard application structure, . . . you can pretty well guess the purpose of the files and directories. © Jim Shingler Wednesday, May 13, 2009 10
  • 11. Griffon Commands © Jim Shingler Wednesday, May 13, 2009 11
  • 12. Plugins © Jim Shingler Wednesday, May 13, 2009 12
  • 13. Start Small • Swing and SwingX Builder • GUI Components • About Box • Define and Process Actions © Jim Shingler Wednesday, May 13, 2009 13
  • 14. DEMO • Create Count App • Add Button • Build and Initialize “Click Action” • Process the Click Action • Install and Enable SwingXBuilder • Build and Initialize Menus • Build and Initialize “Menu Actions” • Process the Menu Actions © Jim Shingler Wednesday, May 13, 2009 14
  • 15. Controller import javax.swing.JOptionPane class CountingController { // these will be injected by Griffon def model def view def builder void mvcGroupInit(Map args) { // this method is called after model and view are injected } def click = { evt = null -> model.count++ } def exit = { evt = null -> app.shutdown() } def showAbout = { evt = null -> builder.optionPane().showMessageDialog(null, 'This is the Counting Application') } } © Jim Shingler Wednesday, May 13, 2009 15
  • 16. Model import groovy.beans.Bindable Adds Property @Bindable Change Support class CountingModel { def count = 0 } to the model © Jim Shingler Wednesday, May 13, 2009 16
  • 17. View and Menu View application(title:'sample2', /*size:[320,480], */location:[200,200], pack:true, locationByPlatform:false) { // add content here build(Actions) Loads and runs Actions and MenuBar scripts inline build(MenuBar) button(id:'clickButton', text:bind{ model.count }, action: clickAction) } Data Binding. Observe the change in the model MenuBar Execute the “clickAction” jxmenuBar { menu(text: 'File', mnemonic: 'F') { menuItem(exitAction) Use the action to define } the menu item glue() menu(text: 'Help', mnemonic: 'H') { menuItem(aboutAction) } } © Jim Shingler Wednesday, May 13, 2009 17
  • 18. Actions // create the actions Closure to run when action(id: 'clickAction', the action is name: 'Click Me', executed closure: controller.&click, shortDescription: 'Increment the Click Count' ) action(id: 'exitAction', name: 'Exit', closure: controller.exit, mnemonic: 'x', accelerator: 'F4', shortDescription: 'Exit SimpleUI' ) action(id: 'aboutAction', name: 'About', closure: controller.showAbout, mnemonic: 'A', accelerator: 'F1', shortDescription: 'Find out about SimpleUI' ) © Jim Shingler Wednesday, May 13, 2009 18
  • 19. Threading the GUI It isn’t that bad © Jim Shingler Wednesday, May 13, 2009 19
  • 20. Rules of Thumb • Painting and UI Operations need to be done in the EventDispatchThread (EDT) • Everything else should be done outside the EDT • Java 6 has SwingWorker, Java 5 has SwingLabs Swingworker But that just isn’t Groovy enough for Griffon © Jim Shingler Wednesday, May 13, 2009 20
  • 21. Griffon Threading • Build the UI in the EDT SwingBuilder.build { . . . } • Long Running code outside the EDT doOutside { . . . } Creates thread and runs closure • code inside the EDT edt { . . . } Do synchronously in EDT doLater { . . . } Do asynchronously in EDT © Jim Shingler Wednesday, May 13, 2009 21
  • 22. DEMO © Jim Shingler Wednesday, May 13, 2009 22
  • 23. Model import groovy.beans.Bindable @Bindable class CountingModel { def count = 0 def countSlow = 0 def countConcurrent = 0 } © Jim Shingler Wednesday, May 13, 2009 23
  • 24. View application(title:'counting', /*size:[320,480], location:[50,50],*/ pack:true, locationByPlatform:true) { build(Actions) build(MenuBar) gridLayout() button(id:'clickButton', text:bind {model.count}, action: clickAction) label(text:bind {model.count}) button(id:'slowClickButton', text:"Slow Click", action: slowClickAction) label(text:bind {model.countSlow}) button(id:'concurrentClickButton', text:"Concurrent Click", action: concurrentClickAction) label(text:bind {model.countConcurrent}) } © Jim Shingler Wednesday, May 13, 2009 24
  • 25. Actions // create the actions action(id: 'clickAction', name: 'Click', closure: controller.&click, shortDescription: 'Increment the Click Count' ) action(id: 'clickActionSlow', name: 'Click Slow', closure: controller.&clickSlow, shortDescription: 'Increment the Click Count Slow' ) action(id: 'clickActionConcurrent', name: 'Click Concurrent', closure: controller.&clickConcurrent, shortDescription: 'Increment the Click Count Concurrent' ) action(id: 'exitAction', name: 'Exit', closure: controller.exit, mnemonic: 'x', accelerator: 'F4', shortDescription: 'Exit SimpleUI' ) action(id: 'aboutAction', name: 'About', closure: controller.showAbout, mnemonic: 'A', accelerator: 'F1', shortDescription: 'Find out about SimpleUI' ) © Jim Shingler Wednesday, May 13, 2009 25
  • 26. Controller import javax.swing.JOptionPane class CountingController { // these will be injected by Griffon def model def view void mvcGroupInit(Map args) { } def click = { evt -> model.count++ } def clickSlow = { evt = null -> Thread.sleep(5000) model.countSlow++ } def clickConcurrent = { evt = null -> doOutside { Thread.sleep(5000) edt { // Sync model.countConcurrent++ } } } def exit = { evt = null -> System.exit(0) } def showAbout = { evt = null -> JOptionPane.showMessageDialog(null, '''This is the SimpleUI Application''') } } © Jim Shingler Wednesday, May 13, 2009 26
  • 27. Twitter Clone Enhancements © Jim Shingler Wednesday, May 13, 2009 27
  • 28. Render Status XML import grails.converters.* class StatusController { def twitterCache def index = { def messages = twitterCache.get(principalInfo.username)?.value if(!messages) { messages = findStatusMessages() twitterCache.put new Element(principalInfo.username, messages) } def feedOutput = { . . . } withFormat { html([messages:messages]) xml { render messages as XML} rss { render(feedType:"rss", feedOutput)} } } . . . © Jim Shingler Wednesday, May 13, 2009 28
  • 29. Render Person XML import grails.converters.* class PersonController { ... def findByUsername = { def p = Person.findByUsername(params.username) withFormat { html person:p xml { render p as XML } } } ... © Jim Shingler Wednesday, May 13, 2009 29
  • 30. def show = { def person = Person.get(params.id) if (!person) { flash.message = "Person not found with id $params.id" redirect action: list return } List roleNames = [] for (role in person.authorities) { roleNames << role.authority } roleNames.sort { n1, n2 -> n1 <=> n2 } withFormat { html ( [person: person, roleNames: roleNames] ) xml { render person as XML } } // [person: person, roleNames: roleNames] } © Jim Shingler Wednesday, May 13, 2009 30
  • 31. Acegi Basic Authentication grails-app/conf/SecurityConfig.groovy security { // see DefaultSecurityConfig.groovy for all settable/overridable properties active = true basicProcessingFilter = true loginUserDomainClass = "Person" authorityDomainClass = "Authority" requestMapClass = "Requestmap" } © Jim Shingler Wednesday, May 13, 2009 31
  • 32. Acegi Basic Authentication grails-app/conf/spring/resources.groovy beans = { authenticationEntryPoint(org.springframework.security.ui.basicauth. BasicProcessingFilterEntryPoint) { realmName = 'Grails Realm' } twitterCache(org.springframework.cache.ehcache.EhCacheFactoryBean) { timeToLive = 1200 } } © Jim Shingler Wednesday, May 13, 2009 32
  • 33. Griffon Twitter Clone Client © Jim Shingler Wednesday, May 13, 2009 33
  • 34. Requirements • Login • Display User Info • Display Statuses (Tweets) • Update Statuses(Tweets) • Send My Own Status (Tweet) © Jim Shingler Wednesday, May 13, 2009 34
  • 35. Overview MVC Triad MenuBar Controller View ToolBar StatusBar Model Tips About Twitter Service </xml> Twitter Clone © Jim Shingler Wednesday, May 13, 2009 35
  • 36. Let’s get to Work © Jim Shingler Wednesday, May 13, 2009 36
  • 37. Login Refresh ToolBar User Info Statuses / Tweets Update Status © Jim Shingler Wednesday, May 13, 2009 37
  • 38. © Jim Shingler Wednesday, May 13, 2009 38
  • 39. Other Griffon Apps © Jim Shingler Wednesday, May 13, 2009 39
  • 40. © Jim Shingler Wednesday, May 13, 2009 40
  • 41. © Jim Shingler Wednesday, May 13, 2009 41
  • 42. © Jim Shingler Wednesday, May 13, 2009 42
  • 43. © Jim Shingler Wednesday, May 13, 2009 43
  • 44. © Jim Shingler Wednesday, May 13, 2009 44
  • 45. © Jim Shingler Wednesday, May 13, 2009 45
  • 46. The Code http://github.com/jshingler/gr8conf_2009/tree/master © Jim Shingler Wednesday, May 13, 2009 46
  • 47. Founders Danno Ferrin http://shemnon.com/speling Andres Almiray http://jroller.com/aalmiray James Williams http://jameswilliams.be/blog © Jim Shingler Wednesday, May 13, 2009 47
  • 48. Resources • Griffon • griffon.codehause.org • griffon-user@groovy.codehause.org • Grails • www.grails.org Coming • Books Soon © Jim Shingler Wednesday, May 13, 2009 48
  • 49. Resources • dev@griffon.codehaus.org is a medium volume list useful for those interested in ongoing developments • scm@griffon.codehaus.org is a high volume list that logs commits and issues • user@griffon.codehaus.org is a high volume list is for questions and general discussion about Griffon • You can find a great archive support at MarkMail, http://griffon.markmail.org. © Jim Shingler Wednesday, May 13, 2009 49
  • 50. Conclusion Thank You for your time • Blog: http://jshingler.blogspot.com • Email: ShinglerJim@gmail.com • LinkedIn: http://www.linkedin.com/in/jimshingler • Twitter: @jshingler © Jim Shingler Wednesday, May 13, 2009 50