{"id":103,"date":"2009-04-03T18:57:47","date_gmt":"2009-04-04T03:57:47","guid":{"rendered":"https:\/\/www.kellyrob99.com\/blog\/?p=103"},"modified":"2010-02-28T20:42:22","modified_gmt":"2010-03-01T05:42:22","slug":"swingset-on-griffon","status":"publish","type":"post","link":"https:\/\/www.kellyrob99.com\/blog\/2009\/04\/03\/swingset-on-griffon\/","title":{"rendered":"SwingSet on Griffon"},"content":{"rendered":"<p>So as&nbsp; as learning experience, I&#8217;ve decided to try cutting the&nbsp; <a href=\"https:\/\/swingset3.dev.java.net\/\">SwingSet demo application<\/a> over to Groovy and <a class=\"zem_slink\" href=\"http:\/\/groovy.codehaus.org\/Griffon\" title=\"Griffon (framework)\" rel=\"homepage\">Griffon<\/a>. To make it a little more interesting, I&#8217;m going to base it off of the <a href=\"http:\/\/swinglabs.org\/demos.jsp\">SwingX version<\/a>.<\/p>\n<p>The SwingX widgets have been a pleasure to work with in the past, and with the <a href=\"http:\/\/griffon.codehaus.org\/SwingxBuilder+Plugin\">swingX plugin<\/a>, it takes not a single line of extra code in order to use them.&nbsp; The underlying <a href=\"http:\/\/groovy.codehaus.org\/SwingXBuilder\">SwingXBuilder<\/a> provides factories which override the standard <a href=\"http:\/\/groovy.codehaus.org\/Swing+Builder\">SwingBuilder<\/a> syntax to replace the standard widget set with the SwingX equivalents. Simply add the prefix &#8216;jx&#8217; to the standard SwingBuilder node calls and you&#8217;re in business.<\/p>\n<p>Along the way I&#8217;m going to incorporate the <a href=\"http:\/\/griffon.codehaus.org\/Fest+Plugin\">fest<\/a> and <a href=\"http:\/\/griffon.codehaus.org\/CodeCoverage+Plugin\">cobertura<\/a> plugins to test out the UI. I&#8217;ve never used fest before but it seems that the only real requirement is to remember to give your components a uniquely identifiable id. There are additional ways of looking up components with fest, for sure, but unique ids should cover this application&#8217;s needs quite nicely. Using both together is a simple exercise on the command line.<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">griffon run-fest -cobertura<\/pre>\n<p>Under the hood, Griffon uses <a href=\"http:\/\/testng.org\/doc\/index.html\">TestNG<\/a>, so the test class can also take advantage of some nice familiar annotations to assist configuration. Code coverage and testing results are provided by default in an html format, which anyone who likes their test coverage will be infinitely familiar with.&nbsp; All in all, the experience of setup and execution of the testing framework is pretty painless.<\/p>\n<p>The SwingSet demo is actually laid out pretty nicely for testing in the first place. There&#8217; s a top level MainWindow class, which accepts a DemoPanel parameter. The full demo launches with a SwingXDemo subclass of DemoPanel that aggregates other subclasses of the same into a tabbed pane. Tests are free to call the MainWindow class with any of the individual panels as a parameter, so testing them on their own using fest looks like it would be a cinch.&nbsp; In Griffon terms this roughly translates to a root MVC group that composes another MVC group that is specified by id. Easier to show than to explain, with an example of a call that would go in the controller:<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">\r\ncreateMVCGroup(mvcGroupIDParam, uid,   &#x5B;... param map ...] )\r\n<\/pre>\n<p>The first thing created in the SwingSet UI is the menu, so that&#8217;s what I created first as well. In the view class:<\/p>\n<pre class=\"brush: groovy; smart-tabs: true; title: ; notranslate\" title=\"\">\r\n actions {\r\n    action(id: &quot;quitAction&quot;,\r\n            name: model.QUIT_NAME,\r\n            mnemonic: &quot;Q&quot;,\r\n            accelerator: shortcut(&quot;Q&quot;),\r\n            closure: controller.quit)\r\n  }\r\n\r\n  menuBar {\r\n    menu(model.MENU_NAME) {\r\n      menuItem(name: model.QUIT_NAME, action:quitAction)\r\n    }\r\n  }\r\n<\/pre>\n<p>The component names are defined in the model class so that they can easily be extracted later for testing purposes.<br \/>\nIncluding the fest plugin with Griffon adds a target which is used to create a new test, which will prompt you for a test name.<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">create-fest-test<\/pre>\n<p>The new test class is created with all of the necessary code to let fest launch the base application frame. This first test is very simple, just making sure that our single menu item is present in the GUI.<\/p>\n<pre class=\"brush: groovy; smart-tabs: true; title: ; notranslate\" title=\"\">\r\n  @Test\r\n  void testQuitMenuItemPresent() \r\n  {\r\n    Assert.assertNotNull( window.menuItem(GriffonSwingSet3Model.QUIT_NAME) )\r\n  }\r\n<\/pre>\n<p>That&#8217;s really all it takes to launch a new application using the test harness and verify UI component state. Man, can I think of a couple of times in the past where that might have come in handy \ud83d\ude42<\/p>\n<p>Next, step is cutting over the first SwingSet DemoPanel, a demonstration of JXBusyLabel &#8211; 635 lines of the usual Swing inner classes and boilerplate GridBagLayout constraints code. Really looking forward to seeing how it looks in Groovy.<\/p>\n<div class=\"zemanta-pixie\"><a class=\"zemanta-pixie-a\" href=\"http:\/\/reblog.zemanta.com\/zemified\/16488263-27eb-48d8-a2e7-387ff800c515\/\" title=\"Zemified by Zemanta\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"zemanta-pixie-img\" src=\"https:\/\/i0.wp.com\/img.zemanta.com\/reblog_c.png\" alt=\"Reblog this post [with Zemanta]\" \/><\/a><span class=\"zem-script more-related pretty-attribution\"><script type=\"text\/javascript\" src=\"http:\/\/static.zemanta.com\/readside\/loader.js\" defer=\"defer\"><\/script><\/span><\/div>\n","protected":false},"excerpt":{"rendered":"<p>So as&nbsp; as learning experience, I&#8217;ve decided to try cutting the&nbsp; SwingSet demo application over to Groovy and Griffon. To make it a little more interesting, I&#8217;m going to base it off of the SwingX version. The SwingX widgets have been a pleasure to work with in the past, and with the swingX plugin, it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[6],"tags":[38,37,20,257,258,17,18,36],"class_list":["post-103","post","type-post","status-publish","format-standard","hentry","category-dev","tag-cobertura","tag-fest","tag-griffon","tag-groovy","tag-java","tag-model-view-controller","tag-swing","tag-swingset"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/prjtg-1F","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/comments?post=103"}],"version-history":[{"count":51,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/103\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/103\/revisions\/150"}],"wp:attachment":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/media?parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/categories?post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/tags?post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}