Your SlideShare is downloading. ×
0
Griffon in Front
 Grails in Back
 Leveraging Grails with Griffon
Griffon in Front
 Grails in Back
 Leveraging Grails with Griffon
Abstract
Groovy and Grails have given us the ability to leverage the
strength of the Java Platform (and Eco System) and th...
Introduction
My name is Jim Shingler
Chief Technical Architect
President of Genuine Solutions
Beginning Groovy and Grails
...
Griffon Founders
Griffon Founders

   Danno Ferrin
   http://shemnon.com/speling

   Andres Almiray
   http://jroller.com/aalmiray

   Jame...
Common Complaints
   about Swing
Its hard
Have to code too much
Code is complex
Not many Advanced GUI Components (Myth)
Start Small
• Swing and SwingX Builder
• GUI Components
• About Box
• Define and Process Actions
Builders
      The Builder Pattern is a software design pattern. The
      intention is to separate the construction of a
...
GUI Builders
•   SwingBuilder
    Applies the Builder Pattern to the construction of Swing
    “Makes Swing Groovy”

•   S...
Plugins
     A plugin is a Griffon extension point. Conceptually, it
     is similar to the plugins found in modern IDEs.
...
DEMO
• Create Count App
• Add Button
• Build and Initialize “Click Action”
• Process the Click Action
• Install and Enable...
DEMO
• Create Count App
• Add Button
• Build and Initialize “Click Action”
• Process the Click Action
• Install and Enable...
Controller
import javax.swing.JOptionPane

class Sample2Controller {
    // these will be injected by Griffon
    def mode...
Model
import groovy.beans.Bindable

@Bindable
class Sample2Model {
    def count = 0
}
View
application(title:'sample2', /*size:[320,480], */location:[200,200],
pack:true, locationByPlatform:false) {
    // ad...
Actions
// create the actions
action(id: 'clickAction',
         name: 'Click Me',
         closure: controller.&click,
  ...
Goal
Goal
 Menu Bar
  Tool Bar




Content Area




 Status Bar
Goal
 Menu Bar
  Tool Bar
Login Dialog


Content Area




 Tips Dialog




 Status Bar
Planning
•   Menu Bar

•   Tool Bar

•   Status Bar

•   About Box

•   Tips

•   Login Dialog

•   Master / Detail Conten...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box

•   Tips

•   Login Dialog

•   Master / Detail...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box

•   Tips

•   Login Dialog

•   Master / Detail...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Planning
•   Menu Bar       
•   Tool Bar

•   Status Bar

•   About Box      
•   Tips

•   Login Dialog

•   Master / ...
Organization
             MVC Triad
Controller               View



                Model
Organization
             MVC Triad
Controller                View



                Model




                        Gr...
Organization
Controller              View



              Model




                      Griffon Framework
Organization
                                     Menu Bar
Controller              View



              Model




       ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                     Menu Bar
Controller              View
                                  ...
Organization
                                          Menu Bar
 Controller                  View
                        ...
Interaction with
RESTful WebServices
        SQL        HTTP       Grails
Action
       Method      Method   Convention
Cr...
Loading Data
class GCollabTodoController {
...

  void loadData() {
      setStatus(quot;Loading Dataquot;)
      busy

  ...
Let’s Look at the Code
class Get{
    String url
    QueryString queryString = new QueryString()
    String text


                              ...
Save Todo
void saveTodo(event) {
     fillSelectedTodoFromView()

    def todo = selectedTodo()

     if(shouldBeSaved(tod...
Service Save
static void save(appContext, todo) {
         def userContext = appContext.userContext

        def put = new...
package http.utils
class Put{
     String url
     QueryString queryString = new QueryString()
     String content



    ...
RESTFul WebServices
class UserInfoController {
    def index = { redirect(action:show,params:params) }

    def show = {
          def result ...
class UserInfoController {
    def index = { redirect(action:show,params:params) }

    def show = {
          def result ...
Other Griffon Apps
http://github.com/jshingler/gcollabtodo/tree/master
Resources
•   Introduction to Groovy
•   Groovy Basics
•   More Advanced Groovy
•   Introduction to Grails
•   Building th...
Resources
• Griffon
  • griffon.codehause.org
  • griffon-user@groovy.codehause.org
• Grails
  • www.grails.org
          ...
Resources
• SwingLabs
  • swinglabs.org
• MigLayout
  • miglayout.org
• GlazedLists
  • publicobject.com/glazedlists
Conclusion
Thank You for your time

 •   Blog:
     http://jshingler.blogspot.com

 •   Email:
     ShinglerJim@gmail.com
...
Griffon In Front Grails In Back
Griffon In Front Grails In Back
Griffon In Front Grails In Back
Griffon In Front Grails In Back
Griffon In Front Grails In Back
Griffon In Front Grails In Back
Upcoming SlideShare
Loading in...5
×

Griffon In Front Grails In Back

14,486

Published on

Published in: Technology

Transcript of "Griffon In Front Grails In Back"

  1. 1. Griffon in Front Grails in Back Leveraging Grails with Griffon
  2. 2. Griffon in Front Grails in Back Leveraging Grails with Griffon
  3. 3. 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 applicaiton to interact with a Grails backend.
  4. 4. 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
  5. 5. Griffon Founders
  6. 6. Griffon Founders Danno Ferrin http://shemnon.com/speling Andres Almiray http://jroller.com/aalmiray James Williams http://jameswilliams.be/blog
  7. 7. Common Complaints about Swing Its hard Have to code too much Code is complex Not many Advanced GUI Components (Myth)
  8. 8. Start Small • Swing and SwingX Builder • GUI Components • About Box • Define and Process Actions
  9. 9. Builders The Builder Pattern is a software design pattern. The intention is to separate the construction of a complex object from its representation so that the same construction process can create different representations. Often, the Build Patter is used to build Products in accordance to the Composite pattern. Swing is a complex hierarchy, . . . Source: Wikipedia Sounds like an opportunity
  10. 10. GUI Builders • SwingBuilder Applies the Builder Pattern to the construction of Swing “Makes Swing Groovy” • SwingXBuilder Extends SwingBuilder adding the SwingLabs Components • JideBuilder Extends SwingBuilder adding JIDE Components • SWTBuilder Applies the Builder Pattern to the construction of SWT “Makes SWT Groovy”
  11. 11. Plugins A plugin is a Griffon extension point. Conceptually, it is similar to the plugins found in modern IDEs. A plugin is a technique to encapsulate functionality that can be reused across multiple applications. Griffon’s plugin community has just begun but it is growing fast. See: >griffon list-plugins http://grails.org/Plugins http://www.grails.org/The+Plug-in+Developers+Guide
  12. 12. 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
  13. 13. 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 NOTE: The Code included on the next several pages has been enhanced based upon questions asked in the session.
  14. 14. Controller import javax.swing.JOptionPane class Sample2Controller { // these will be injected by Griffon def model def view void mvcGroupInit(Map args) { // this method is called after model and view are injected } def click = { evt = null -> model.count++ } def exit = { evt = null -> System.exit(0) } def showAbout = { evt = null -> JOptionPane.showMessageDialog(null, '''This is the SimpleUI Application''') } }
  15. 15. Model import groovy.beans.Bindable @Bindable class Sample2Model { def count = 0 }
  16. 16. View application(title:'sample2', /*size:[320,480], */location:[200,200], pack:true, locationByPlatform:false) { // add content here build(Actions) build(MenuBar) button(id:'clickButton', text:bind{ model.count }, action: clickAction) } MenuBar jxmenuBar { menu(text: 'File', mnemonic: 'F') { menuItem(exitAction) } glue() menu(text: 'Help', mnemonic: 'H') { menuItem(aboutAction) } }
  17. 17. Actions // create the actions action(id: 'clickAction', name: 'Click Me', 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' )
  18. 18. Goal
  19. 19. Goal Menu Bar Tool Bar Content Area Status Bar
  20. 20. Goal Menu Bar Tool Bar Login Dialog Content Area Tips Dialog Status Bar
  21. 21. Planning • Menu Bar • Tool Bar • Status Bar • About Box • Tips • Login Dialog • Master / Detail Content Area •Table and Fields • Wire it together with Actions • Make calls to Web Services
  22. 22. Planning • Menu Bar  • Tool Bar • Status Bar • About Box • Tips • Login Dialog • Master / Detail Content Area •Table and Fields • Wire it together with Actions • Make calls to Web Services
  23. 23. Planning • Menu Bar  • Tool Bar • Status Bar • About Box • Tips • Login Dialog • Master / Detail Content Area •Table and Fields • Wire it together with Actions • Make calls to Web Services
  24. 24. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area •Table and Fields • Wire it together with Actions • Make calls to Web Services
  25. 25. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area •Table and Fields • Wire it together with Actions • Make calls to Web Services
  26. 26. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area Glazed Lists •Table and Fields • Wire it together with Actions • Make calls to Web Services
  27. 27. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area Glazed Lists •Table and Fields • Wire it together with Actions • Make calls to Web Services
  28. 28. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area Glazed Lists •Table and Fields • Wire it together with Actions  • Make calls to Web Services
  29. 29. Planning • Menu Bar  • Tool Bar • Status Bar • About Box  • Tips • Login Dialog • Master / Detail Content Area Glazed Lists •Table and Fields • Wire it together with Actions  • Make calls to Web Services
  30. 30. Organization MVC Triad Controller View Model
  31. 31. Organization MVC Triad Controller View Model Griffon Framework
  32. 32. Organization Controller View Model Griffon Framework
  33. 33. Organization Menu Bar Controller View Model Griffon Framework
  34. 34. Organization Menu Bar Controller View About Dialog Model Griffon Framework
  35. 35. Organization Menu Bar Controller View About Dialog Content Pane Model Griffon Framework
  36. 36. Organization Menu Bar Controller View About Dialog Content Pane Model Tool Bar Griffon Framework
  37. 37. Organization Menu Bar Controller View About Dialog Content Pane Model Tool Bar Status Bar Griffon Framework
  38. 38. Organization Menu Bar Controller View About Dialog Content Pane Model Tool Bar Services Status Bar Griffon Framework
  39. 39. Organization Menu Bar Controller View About Dialog Content Pane Model Tool Bar Services Status Bar Http Utils Get Griffon Framework Put Post Delete
  40. 40. Organization Menu Bar Controller View About Dialog Content Pane Model Tool Bar Services Status Bar Http Utils Get Griffon Framework Put Post Delete Rest Controller
  41. 41. Interaction with RESTful WebServices SQL HTTP Grails Action Method Method Convention Create INSERT PUT create Read SELECT GET show Update UPDATE POST update Delete DELETE DELETE delete Collect SELECT list
  42. 42. Loading Data class GCollabTodoController { ... void loadData() { setStatus(quot;Loading Dataquot;) busy model.todos.clear() model.todos.addAll (TodoService.list(appContext)) norm setStatus(quot;Finished Loading Dataquot;) } class TodoService { static String APP_URL = 'http://localhost:8080/collab-todo/json/todo' static List list(appContext) { def userContext = appContext.userContext def get = new Get(url: APP_URL, userName: userContext.userName, password: userContext.password) def todoJson = get.text def str = JsonUtil.makeJSONStrict(todoJson) def jsonarray = JSONSerializer.toJSON(str) def todo def outputList = [] jsonarray.each { todo = JsonUtil.jsonToObject(it.toString(), Todo.class) outputList.add todo } return outputList }
  43. 43. Let’s Look at the Code
  44. 44. class Get{ String url QueryString queryString = new QueryString() String text Get (HttpUtils) def userName def password String getText() try { def response def conn = new URL(toString()).openConnection() conn.requestMethod = quot;GETquot; conn.doOutput = true if (userName && password) { conn.setRequestProperty(quot;Authorizationquot;, quot;Basic ${userName}:${password}quot;) } def content if (conn.responseCode == conn.HTTP_OK) { response = conn.content.text } else { response = quot;URL: quot; + this.toString() + quot;nquot; + quot;RESPONSE CODE: quot; + conn.responseCode throw new ResourceException(response) } conn.disconnect() return response } catch (Exception e) { println quot;Caught Exception ${e}quot; throw new ResourceException(e) } } String toString(){ return url + quot;?quot; + queryString.toString() }
  45. 45. Save Todo void saveTodo(event) { fillSelectedTodoFromView() def todo = selectedTodo() if(shouldBeSaved(todo)) { execWithExceptionHandling { TodoService.save(appContext, todo) loadData() } } else { JOptionPane.showMessageDialog(frame, quot;If this had been a completed application the Todo would have been updated:quot;) } } private boolean shouldBeSaved(todo) { if (todo.id == quot;quot; || !todo.id ) { return true } return false } private void fillSelectedTodoFromView() { selectedTodo().with { name = view.nameTextField?.text priority = view.priorityComboBox?.selectedItem selectedTodo().status = view.statusComboBox?.selectedItem completedDate = view.completedDateField?.date createdDate = view.createDateField?.date dueDate = view.dueDateField?.date note = view.noteTextField?.text } }
  46. 46. Service Save static void save(appContext, todo) { def userContext = appContext.userContext def put = new Put(url: APP_URL, userName: userContext.userName, password: userContext.password) put.queryString.add(quot;namequot;, todo.name) put.queryString.add(quot;priorityquot;, todo.priority) put.queryString.add(quot;statusquot;, todo.status) put.queryString.add(quot;notequot;, todo.note) put.queryString.add(quot;owner.idquot;, userContext.id) put.queryString.addDate(quot;createdDatequot;, todo.createdDate) def putResponse = put.text }
  47. 47. package http.utils class Put{ String url QueryString queryString = new QueryString() String content Put (HttpUtils) String contentType String text def userName def password String getText(){ def conn = new URL(url).openConnection() conn.setRequestMethod(quot;PUTquot; ) conn.setRequestProperty(quot;Content-Typequot; , contentType) conn.doOutput = true conn.doInput = true if (userName && password) { conn.setRequestProperty(quot;Authorizationquot;, quot;Basic ${userName}:${password}quot;) } conn.outputStream.withWriter { out -> out.write(queryString.toString()) out.flush() out.close() } def response if (conn.HTTP_OK == conn?.responseCode) { response = conn.content.text } else { response = quot;URL: quot; + this.toString() + quot;nquot; + quot;RESPONSE CODE: quot; + responseCode } conn.disconnect() return response } String toString(){ return url + quot;?quot; + queryString.toString() } }
  48. 48. RESTFul WebServices
  49. 49. class UserInfoController { def index = { redirect(action:show,params:params) } def show = { def result = session.user format(result) } def beforeInterceptor = { def authHeader = request.getHeader(quot;Authorizationquot;) if (authHeader) { def tokens = authHeader.split(' ') def user_password = tokens[1] tokens = user_password.split(':') def userid = tokens[0] def password = tokens[1] // At this point, the userid and password could be verified // to make sure that the person making the request is authenticated // // << AUTHENTICATION LOGIC / CALL >> // // Put look up the user object and put it into session for use // later by the controllers. def user = User.findByUserName(userid) if (user) { session.user = user } else { session.user = null } } } private format(obj) { def restType = (params.rest == quot;restquot;)?quot;XMLquot;:quot;JSONquot; println obj.quot;encodeAs$restTypequot;() render obj.quot;encodeAs$restTypequot;() } }
  50. 50. class UserInfoController { def index = { redirect(action:show,params:params) } def show = { def result = session.user format(result) } def beforeInterceptor = { def authHeader = request.getHeader(quot;Authorizationquot;) if (authHeader) { def tokens = authHeader.split(' ') def user_password = tokens[1] tokens = user_password.split(':') def userid = tokens[0] def password = tokens[1] // At this point, the userid and password could be verified // to make sure that the person making the request is authenticated // // << AUTHENTICATION LOGIC / CALL >> // // Put look up the user object and put it into session for use // later by the controllers. def user = User.findByUserName(userid) if (user) { session.user = user } else { session.user = null } } } private format(obj) { def restType = (params.rest == quot;restquot;)?quot;XMLquot;:quot;JSONquot; println obj.quot;encodeAs$restTypequot;() render obj.quot;encodeAs$restTypequot;() } }
  51. 51. Other Griffon Apps
  52. 52. http://github.com/jshingler/gcollabtodo/tree/master
  53. 53. Resources • Introduction to Groovy • Groovy Basics • More Advanced Groovy • Introduction to Grails • Building the User Interface • Building Domains and Services • Security in Grails • Web 2.0—Ajax and Friends • Web Services • Reporting • Batch Processing • Deploying and Upgrading • Alternative Clients
  54. 54. Resources • Griffon • griffon.codehause.org • griffon-user@groovy.codehause.org • Grails • www.grails.org Coming • Books Soon
  55. 55. Resources • SwingLabs • swinglabs.org • MigLayout • miglayout.org • GlazedLists • publicobject.com/glazedlists
  56. 56. Conclusion Thank You for your time • Blog: http://jshingler.blogspot.com • Email: ShinglerJim@gmail.com • LinkedIn: http://www.linkedin.com/in/jimshingler • Twitter: http://www.twitter.com/jshingler
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×