<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6639026537345948621</id><updated>2012-01-12T22:24:07.714-08:00</updated><category term='flash'/><category term='gwt2swf'/><category term='javascript'/><category term='cross-site'/><category term='choosel'/><category term='ec2'/><category term='latex'/><category term='community'/><category term='load'/><category term='gwt'/><category term='google gadget'/><category term='poster'/><category term='event'/><category term='benchmark'/><category term='adobe'/><category term='IBM Mashup Center'/><category term='analytics'/><category term='business intelligence'/><category term='ontology'/><category term='listener'/><category term='exhibit'/><category term='iContext'/><category term='presentation'/><category term='web2se'/><category term='visweek'/><category term='external interface'/><category term='css'/><category term='biomedical'/><category term='window'/><category term='software engineering'/><category term='bugzillametrics'/><category term='Software'/><category term='xss'/><category term='ibm jazz'/><category term='IBM University Days'/><category term='mashup'/><category term='Book'/><category term='persevere'/><category term='bio-mixer'/><category term='iWidget'/><category term='infovis'/><category term='paper'/><category term='visualization'/><category term='workshop'/><category term='research'/><category term='google maps'/><category term='cloud computing'/><category term='cascon'/><category term='rgba'/><category term='protovis-gwt'/><category term='flex'/><category term='handler'/><category term='Open Source'/><category term='novice'/><category term='nomad pim'/><category term='datagrid'/><category term='jsni'/><category term='dojo'/><category term='integration'/><category term='cross-domain'/><category term='Eclipse'/><category term='swf'/><category term='publication'/><category term='user study'/><category term='issue tracking'/><category term='notification'/><category term='FloatingPane'/><category term='writing'/><title type='text'>Lars' Notes</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-179379773725329446</id><published>2011-07-16T12:45:00.003-07:00</published><updated>2011-07-16T12:48:19.943-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protovis-gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Protovis-GWT 0.4.1 released</title><content type='html'>&lt;p&gt;&lt;b&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Protovis-GWT&lt;/a&gt;&lt;/b&gt; is an &lt;strong&gt;open source GWT data visualization module&lt;/strong&gt;.  The goal of Protovis-GWT is to make the &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis JavaScript visualization API&lt;/a&gt; available in GWT by wrapping the original JavaScript code using JSNI.&lt;/p&gt;&lt;p&gt;Protovis-GWT supports a wide range of visualizations (&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Area chart, bar chart, pie chart, line chart, stacked charts, treemap, sunburst, icicle diagram, dendrogram, force-directed graph, arc diagram, matrix diagram, box-and-whisker plot, streamgraph, bullet chart, candlestick chart&lt;/a&gt;). It implements the complete API of the basic Protovis Mark classes (Mark, Area, Bar, Dot, Label, Line, Wedge) and enables you to create custom visualizations in GWT, similar to the ones you can create with the &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis library&lt;/a&gt; in JavaScript.&lt;/p&gt;&lt;p&gt;In Protovis-GWT 0.4.1, support for the Protovis pan and zoom behaviors was added. The ellipse mark type, which is not part of the original Protovis, was added. Protovis-GWT 0.4.1 is now based on GWT 2.3 (instead of 2.1) and supports Internet Explorer 9.&lt;/p&gt;&lt;p&gt;More information on Protovis-GWT:&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Wiki Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Example Visualizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/downloads/list?q=ProtovisGWT-0.4.1"&gt;Downloads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/"&gt;Source Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-179379773725329446?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/179379773725329446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=179379773725329446' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/179379773725329446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/179379773725329446'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/07/protovis-gwt-041-released.html' title='Protovis-GWT 0.4.1 released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-390643057240754747</id><published>2011-03-21T16:57:00.004-07:00</published><updated>2011-07-16T12:51:26.749-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protovis-gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Protovis-GWT 0.4 Released</title><content type='html'>&lt;p&gt;&lt;b&gt;Update: A newer version of Protovis-GWT has been released.&lt;/b&gt; Please see the &lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;wiki page&lt;/a&gt; for the latest information on Protovis-GWT.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Protovis-GWT&lt;/a&gt;&lt;/b&gt; is an &lt;strong&gt;open source GWT data visualization module&lt;/strong&gt;.  The goal of Protovis-GWT is to make the &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis JavaScript visualization API&lt;/a&gt; available in GWT by wrapping the original JavaScript code using JSNI.&lt;/p&gt;&lt;p&gt;Protovis-GWT supports a wide range of visualizations (&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Area chart, bar chart, pie chart, line chart, stacked charts, treemap, sunburst, icicle diagram, dendrogram, force-directed graph, arc diagram, matrix diagram, box-and-whisker plot, streamgraph, bullet chart, candlestick chart&lt;/a&gt;). It implements the complete API of the basic Protovis Mark classes (Mark, Area, Bar, Dot, Label, Line, Wedge) and enables you to create custom visualizations in GWT, similar to the ones you can create with the &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis library&lt;/a&gt; in JavaScript.&lt;/p&gt;&lt;p&gt;In Protovis-GWT 0.4, support for network visualizations (Arc diagram, Force-directed graphs, Matrix diagrams) was added. Several classes were moved into the PV class to align the syntax closer to the original Protovis syntax. A stable sort implementation was added to JsArrayGeneric, and various other API improvements were made.&lt;/p&gt;&lt;p&gt;More information on Protovis-GWT:&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Wiki Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Example Visualizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/downloads/list?q=ProtovisGWT-0.4"&gt;Downloads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/"&gt;Source Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-390643057240754747?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/390643057240754747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=390643057240754747' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/390643057240754747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/390643057240754747'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/03/protovis-gwt-04-released.html' title='Protovis-GWT 0.4 Released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-6358238479992116532</id><published>2011-02-18T10:40:00.002-08:00</published><updated>2011-03-21T16:57:26.662-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protovis-gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Protovis-GWT 0.3 Released</title><content type='html'>&lt;p&gt;&lt;b&gt;Update: A newer version of Protovis-GWT has been released.&lt;/b&gt; Please see the &lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;wiki page&lt;/a&gt; for the latest information on Protovis-GWT.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Protovis-GWT&lt;/a&gt;&lt;/b&gt; is an &lt;strong&gt;open source GWT data visualization module&lt;/strong&gt;.  The goal of Protovis-GWT is to make the &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis JavaScript visualization API&lt;/a&gt; available in GWT by wrapping the original JavaScript code using JSNI.&lt;/p&gt;&lt;p&gt;Protovis-GWT 0.3 implements the complete API of the basic Protovis Mark classes (Mark, Area, Bar, Dot, Label, Line, Wedge).&lt;/p&gt;&lt;p&gt;More information on Protovis-GWT:&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Wiki Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Example Visualizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/downloads/list?q=ProtovisGWT-0.3"&gt;Downloads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/"&gt;Source Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-6358238479992116532?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/6358238479992116532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=6358238479992116532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6358238479992116532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6358238479992116532'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/02/protovis-gwt-03-released.html' title='Protovis-GWT 0.3 Released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-3113163616396631498</id><published>2011-02-11T19:23:00.008-08:00</published><updated>2011-04-22T14:21:52.937-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Choosel Visualization Component Architecture</title><content type='html'>&lt;p&gt;The &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel framework&lt;/a&gt; has been restructured into a more modular architecture that facilitates extensibility and reuse. The new visualization component architecture allows developers to use Choosel visualization components in regular GWT applications, to develop their own Choosel visualization components, and to extend the Choosel visualization workbench. This blog post outlines the architecture, describes its usage scenarios and explains how to update existing Choosel applications.&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/choosel/wiki/VisualizationComponentArchitectureDiagram"&gt;&lt;img src="http://choosel.googlecode.com/svn/wiki/images/choosel-visualization_component_architecture-500px.png" style="border: none;"/&gt;&lt;/a&gt;&lt;span style="text-align: center;"&gt;Visualization Component Architecture Overview (&lt;a href="http://code.google.com/p/choosel/wiki/VisualizationComponentArchitectureDiagram"&gt;enlarge diagram&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The Choosel visualization component architecture separates the core functionality (which is required to use Choosel visualizations in GWT) from the workbench functionality. The visualizations are extracted into separate visualization modules. The architecture consists of three main components:&lt;ul&gt;&lt;li&gt;&lt;b&gt;Core module&lt;/b&gt;: The choosel.core module contains the core functionality that is required by Choosel visualizations. This includes the resource (i.e. data) framework, the management of visualization states (e.g. data, highlighting, selection), the visualization component API, and also more general services such as logging (which wraps &lt;a href="http://code.google.com/p/gwt-log/"&gt;gwt-log&lt;/a&gt;). The choosel.core module needs to be inherited by any GWT module that uses Choosel, whether it is a visualization component, a GWT application or a Choosel workbench.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Visualization modules&lt;/b&gt;: Visualization modules provide one or more visualization components that implement the Choosel visualization component API. They can wrap around other libraries, e.g. GWT modules, JavaScript visualization toolkits, or Flash widgets. Choosel provides several visualization modules (map, timeline, text, chart, and graph) that can be used right away.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Workbench module&lt;/b&gt;: The choosel.workbench module provides the persistence and sharing facilities as well as the visualization workspace.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;This separation of concerns makes reusing and extending Choosel easier. It enables three ways to leverage Choosel in your own projects:&lt;ul&gt;&lt;li&gt;&lt;b&gt;Developing your own visualization components&lt;/b&gt;: You can implement visualization components that adher to the Choosel visualization component API. These visualization components can then be used by yourself and others to take advantage of Choosel features such as view synchronization, selections, highlighting, and details on demand.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Using Choosel visualization components in your GWT application&lt;/b&gt;: You can use one or several Choosel visualization components as widgets in your GWT application to visualize your data.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Creating a Choosel-based workbench&lt;/b&gt;: You can extend the whole Choosel framework to develop your own visualization workbench, for example for a specific application domain.&lt;/li&gt;&lt;/ul&gt;&lt;i&gt;Please note that while the modularization itself is complete, the visualization component API is still under development. We plan to release a first stable version in the next few months.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;To set up a new Choosel project, please take a look at the &lt;a href="http://code.google.com/p/choosel/wiki/DevelopmentSetup"&gt;development setup&lt;/a&gt;. If you are already working on a Choosel-based application, you can update it to use the modular Choosel architecture:&lt;ul&gt;&lt;li&gt;Check out the different Choosel modules (see &lt;a href="http://code.google.com/p/choosel/wiki/DevelopmentSetup"&gt;development setup&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Change the dependencies of your Eclipse project (Right click on project --&gt; Properties --&gt; Java Build Path --&gt; Projects) to reference the new Choosel modules, but not the old one (choosel)&lt;/li&gt;&lt;li&gt;Organize the imports of your .java files (Right click on source folder --&gt; Source --&gt; Organize Imports; then for each class that has problems in the Java editor)&lt;/li&gt;&lt;li&gt;Fix the static imports (if there are unresolved constants or methods: compare with previous version, insert old static imports and change choosel.client to choosel.core.client)&lt;/li&gt;&lt;li&gt;Add the visualization configuration file (see ChooselExampleWorkbenchViewContentDisplaysConfigurationProvider for an example)&lt;/li&gt;&lt;li&gt;Update the client module (see ChooselExampleClientModule for an example)&lt;/li&gt;&lt;li&gt;Change the .gwt.xml file of your project (see choosel.example.workbench for an example module file)&lt;/li&gt;&lt;li&gt;Update the servlet references in the web.xml (change choosel.server to choosel.workbench.server)&lt;/li&gt;&lt;li&gt;Remove old launch config, copy launch config from choosel.example.workbench and adjust it to your project.&lt;/li&gt;&lt;/ul&gt;You should be able to run your modular Choosel application now. If there are still problems, feel free to complain on the &lt;a href="http://groups.google.com/group/choosel"&gt;Choosel mailing list&lt;/a&gt; :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-3113163616396631498?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/3113163616396631498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=3113163616396631498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3113163616396631498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3113163616396631498'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/02/choosel-visualization-component.html' title='Choosel Visualization Component Architecture'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-7214841181696517659</id><published>2011-01-31T20:51:00.005-08:00</published><updated>2011-02-18T10:40:11.010-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protovis-gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Protovis-GWT 0.2 Released</title><content type='html'>&lt;p&gt;&lt;b&gt;Update: A newer version of Protovis-GWT has been released.&lt;/b&gt; Please see the &lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;wiki page&lt;/a&gt; for the latest information on Protovis-GWT.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Protovis-GWT&lt;/a&gt;&lt;/b&gt; is an &lt;strong&gt;open source GWT data visualization module&lt;/strong&gt;.  The goal of Protovis-GWT is to make the &lt;a href="http://vis.stanford.edu/protovis/" rel="nofollow"&gt;Protovis JavaScript visualization API&lt;/a&gt; available in GWT by wrapping the original JavaScript code using JSNI.&lt;/p&gt;&lt;p&gt;Protovis-GWT 0.2 has an improved event handler interface and now supports the hierarchical visualization examples (dendrograms, sunbursts, icicles, indented trees, circle packing, node-link trees, and treemaps) and the bubble chart example from the Protovis example library.&lt;/p&gt;&lt;p&gt;More information on Protovis-GWT:&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Wiki Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Example Visualizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/downloads/list?q=ProtovisGWT-0.2"&gt;Downloads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/"&gt;Source Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-7214841181696517659?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/7214841181696517659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=7214841181696517659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7214841181696517659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7214841181696517659'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/01/protovis-gwt-02-released.html' title='Protovis-GWT 0.2 Released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-3782147608686533805</id><published>2011-01-03T12:44:00.016-08:00</published><updated>2011-01-31T20:58:03.591-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protovis-gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Protovis-GWT 0.1 Released</title><content type='html'>&lt;p&gt;&lt;b&gt;Update: A newer version of Protovis-GWT has been released.&lt;/b&gt; Please see the &lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;wiki page&lt;/a&gt; for the latest information on Protovis-GWT.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Protovis-GWT&lt;/a&gt;&lt;/b&gt; is an &lt;strong&gt;open source GWT data visualization module&lt;/strong&gt;. It wraps the &lt;a href="http://vis.stanford.edu/protovis/" rel="nofollow"&gt;Protovis JavaScript visualization API&lt;/a&gt; for usage in GWT. Protovis-GWT 0.1 (&lt;a href="http://choosel.googlecode.com/files/ProtovisGWT-0.1.jar" rel="nofollow"&gt;Download Module&lt;/a&gt;) is an &lt;strong&gt;early development version&lt;/strong&gt; based on Protovis 3.2 and GWT 2.1. Several examples from the &lt;a href="http://vis.stanford.edu/protovis/ex/" rel="nofollow"&gt;Protovis example gallery&lt;/a&gt; have been &lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;re-implemented using Protovis/GWT&lt;/a&gt;. Protovis-GWT is developed as part of the &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel Visual Data Exploration Framework&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Version 0.1 implements the Protovis functionality for most conventional and custom &lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;examples&lt;/a&gt; from the Protovis website. The support for tree, graph and map visualizations as well as for interaction is still limited. Protovis-GWT currently supports &lt;strong&gt;Chrome&lt;/strong&gt;, &lt;strong&gt;Firefox&lt;/strong&gt; and &lt;strong&gt;Safari&lt;/strong&gt;. IE is not yet supported.&lt;/p&gt; &lt;p&gt;Getting started with Protovis-GWT in your GWT project is easy:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://choosel.googlecode.com/files/ProtovisGWT-0.1.jar" rel="nofollow"&gt;Download the Protovis-GWT module jar file&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Add the jar file to the build path of your GWT project &lt;/li&gt;&lt;li&gt;Inherit &lt;tt&gt;org.thechiselgroup.choosel.protovis.ProtovisGWT&lt;/tt&gt; by adding &lt;tt&gt;&amp;lt;inherits name=&amp;#x27;org.thechiselgroup.choosel.protovis.ProtovisGWT&amp;#x27;/&amp;gt;&lt;/tt&gt; to your GWT module XML definition (&lt;tt&gt;.gwt.xml&lt;/tt&gt;). &lt;/li&gt;&lt;li&gt;Use the Protovis Widget in your code, e.g. &lt;/li&gt;&lt;pre name="code" class="java"&gt;public void onModuleLoad() {&lt;br /&gt;  RootPanel.get().add(new ProtovisWidget() {&lt;br /&gt;    protected void onAttach() {&lt;br /&gt;      super.onAttach();&lt;br /&gt;      initPVPanel();&lt;br /&gt;      // create visualization here...&lt;br /&gt;      getPVPanel().render();&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;}&lt;/pre&gt;&lt;/ol&gt;&lt;p&gt;More information on Protovis-GWT:&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/wiki/ProtovisGWT"&gt;Wiki Page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://web.uvic.ca/~lgrammel/blog/protovis-gwt/index.html"&gt;Example Visualizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/"&gt;Source Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-3782147608686533805?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/3782147608686533805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=3782147608686533805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3782147608686533805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3782147608686533805'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2011/01/protovisgwt-01-released.html' title='Protovis-GWT 0.1 Released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-3331821964512321485</id><published>2010-12-23T02:11:00.003-08:00</published><updated>2010-12-28T08:24:15.133-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='jsni'/><title type='text'>Generic JavaScript Array for GWT objects</title><content type='html'>GWT supports several wrappers for JavaScript arrays, e.g. &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/core/client/JsArray.html"&gt;JsArray&lt;/a&gt;, &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/core/client/JsArrayNumber.html"&gt;JsArrayNumber&lt;/a&gt; and &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/core/client/JsArrayInteger.html"&gt;JsArrayInteger&lt;/a&gt;. However, they all require JavaScript primitives or &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/core/client/JavaScriptObject.html"&gt;JavaScriptObjects&lt;/a&gt;. I needed to pass a JavaScript array containing regular GWT objects to a third party JavaScript library, together with a callback function that resolves specific properties for elements in the array. The skeleton of the array is similar to the JsArray classes provided by GWT (&lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel.protovis/src/org/thechiselgroup/choosel/protovis/client/JsGenericArray.java?r=904"&gt;full source code&lt;/a&gt;):&lt;pre name="code" class="java"&gt;&lt;br /&gt;import com.google.gwt.core.client.JavaScriptObject;&lt;br /&gt;&lt;br /&gt;public class JsGenericArray&amp;lt;T&amp;gt; extends JavaScriptObject {&lt;br /&gt;&lt;br /&gt;  // typical JsArray methods&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;I initially tried to use this array with the following factory method:&lt;pre name="code" class="java"&gt;&lt;br /&gt;  public static native &amp;lt;T&amp;gt; JsGenericArray&amp;lt;T&amp;gt; createGenericArray() /*-{&lt;br /&gt;    return [];&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;/pre&gt;However, I ran into the problem that &lt;code&gt;instanceof Array&lt;/code&gt; tests on this array in the 3rd party libraries returned false (as debugging showed). This is because &lt;a href="http://groups.google.com/group/google-web-toolkit/browse_thread/thread/09d82fa9a8d87832?fwc=1&amp;pli=1"&gt;GWT runs in an iframe and instanceof does not work across frames&lt;/a&gt;. One recommended solution is &lt;a href="http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/"&gt;duck typing&lt;/a&gt;, but this was not an option because I did not want to change the 3rd party JavaScript library. To address this issue, I changed the factory method to return an array object from the main frame in which the JavaScript libraries run:&lt;pre name="code" class="java"&gt;&lt;br /&gt;    public static native &amp;lt;T&amp;gt; JsGenericArray&amp;lt;T&amp;gt; createGenericArray() /*-{&lt;br /&gt;        return new $wnd.Array();&lt;br /&gt;    }-*/;&lt;br /&gt;&lt;/pre&gt;This approach worked with Firefox 3.6 and Chrome 9, but not with Safari (see  &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=17250"&gt;Webkit Bug 17250&lt;/a&gt;). However, I am not a JavaScript expert and would appreciate any feedback on potential shortcomings of this solution, especially concerning cross-browser compatibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-3331821964512321485?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/3331821964512321485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=3331821964512321485' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3331821964512321485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3331821964512321485'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/12/generic-javascript-array-for-gwt.html' title='Generic JavaScript Array for GWT objects'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-7997705335065149583</id><published>2010-11-06T15:00:00.002-07:00</published><updated>2010-11-06T15:00:55.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='novice'/><category scheme='http://www.blogger.com/atom/ns#' term='visweek'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Slides of InfoVis 2010 presentation "How Information Visualization Novices Construct Visualizations"</title><content type='html'>I presented the paper "&lt;a href="http://lgrammel.blogspot.com/2010/07/how-information-visualization-novices.html"&gt;How Information Visualization Novices Construct Visualizations&lt;/a&gt;" at &lt;a href="http://vis.computer.org/VisWeek2010/"&gt;IEEE InfoVis 2010&lt;/a&gt; in Salt Lake City. Here are my slides:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object id="__sse5689034" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelinfovis2010online-101106155834-phpapp02&amp;rel=0&amp;stripped_title=how-information-visualization-novices-construct-visualizations&amp;userName=lgrammel" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5689034" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelinfovis2010online-101106155834-phpapp02&amp;rel=0&amp;stripped_title=how-information-visualization-novices-construct-visualizations&amp;userName=lgrammel" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-7997705335065149583?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/7997705335065149583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=7997705335065149583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7997705335065149583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7997705335065149583'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/11/slides-of-infovis-2010-presentation-how.html' title='Slides of InfoVis 2010 presentation &quot;How Information Visualization Novices Construct Visualizations&quot;'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-3586649572308676604</id><published>2010-10-22T19:32:00.005-07:00</published><updated>2010-10-22T19:39:40.032-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cascon'/><category scheme='http://www.blogger.com/atom/ns#' term='poster'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='exhibit'/><category scheme='http://www.blogger.com/atom/ns#' term='visweek'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Choosel at VisWeek 2010 and at CASCON 2010</title><content type='html'>&lt;b&gt;Interested in data visualization on the web?&lt;/b&gt; There are several &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel&lt;/a&gt;-related events at &lt;a href="http://vis.computer.org/VisWeek2010/index.html"&gt;VisWeek 2010&lt;/a&gt;, &lt;a href="http://www.cser.ca/"&gt;CSER&lt;/a&gt; and &lt;a href="https://www-927.ibm.com/ibm/cas/cascon/"&gt;CASCON 2010&lt;/a&gt;. Choosel is an open-source framework for browser-based data visualization.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/16109235?portrait=0" width="500" height="281" frameborder="0"&gt;&lt;/iframe&gt;&lt;i&gt;Watch video in full screen and HD for better quality&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Oct 24-28&lt;/b&gt;, I will present the InfoVis poster "&lt;a href="http://www.thechiselgroup.org/files/uploads/publications/grammel_choosel_poster_2010.pdf"&gt;Choosel – Web-based Visualization Construction and Coordination for Information Visualization Novices&lt;/a&gt;" at &lt;b&gt;VisWeek 2010&lt;/b&gt;. Here is a preview: &lt;br /&gt;&lt;br /&gt;&lt;div style="width:500px;" id="__ss_5535045"&gt;&lt;object id="__sse5535045" width="500" height="400"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=posterchoosel-camready-101022203212-phpapp02&amp;rel=0&amp;stripped_title=poster-choosel-cam-ready&amp;userName=lgrammel" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5535045" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=posterchoosel-camready-101022203212-phpapp02&amp;rel=0&amp;stripped_title=poster-choosel-cam-ready&amp;userName=lgrammel" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="400"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Oct 31st&lt;/b&gt;, there will be a presentation on Choosel and the Work Item Explorer at &lt;b&gt;CSER&lt;/b&gt;. The Work Item Explorer (developed by Patrick Gorman, Del Myers and &lt;a href="http://ctreude.ca/"&gt;Christoph Treude&lt;/a&gt;) is a research prototype built on Choosel that facilitates the flexible, iterative exploration of Jazz data, focusing primarily on work items.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nov 1-4&lt;/b&gt;, there will be &lt;b&gt;CASCON&lt;/b&gt; exhibits on Choosel and the Work Item Explorer. The Choosel exhibit (Bradley Blashko, Lars Grammel) will be at booth X2 near the Central Tower, and the Work Item Explorer exhibit (Patrick Gorman, Christoph Treude) will be at booth U5. The exhibits are open 5pm to 7pm on Monday (Nov 1), from 8.30am to 7pm on Tuesday and Wednesday (Nov 2 and 3), and from 8.30am to 1pm on Thursday (Nov 4).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-3586649572308676604?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/3586649572308676604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=3586649572308676604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3586649572308676604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3586649572308676604'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/10/choosel-at-visweek-2010-and-at-cascon.html' title='Choosel at VisWeek 2010 and at CASCON 2010'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-618645762378228382</id><published>2010-10-07T15:50:00.003-07:00</published><updated>2010-10-07T15:52:58.225-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='bugzillametrics'/><category scheme='http://www.blogger.com/atom/ns#' term='ibm jazz'/><category scheme='http://www.blogger.com/atom/ns#' term='issue tracking'/><title type='text'>Attracting the Community’s Many Eyes: an Exploration of User Involvement in Issue Tracking</title><content type='html'>User input drives the development of software systems by contributing ideas, reporting bugs and clarifiying requirements. To encourage such feedback, open source projects often provide issue tracking systems (e.g. Bugzilla) that are open to the public. In commercial software development, however, this is often not the case. I was interested if opening issue tracking systems of commercial projects to the public would yield similar community input as is the case for open source projects. Together with Holger Schackmann, &lt;a href="http://uvic.academia.edu/AdrianSchroeter"&gt;Adrian Schr&amp;ouml;ter&lt;/a&gt;, &lt;a href="http://ctreude.ca/"&gt;Christoph Treude&lt;/a&gt; and &lt;a href="http://webhome.cs.uvic.ca/%7Emstorey/"&gt;Margaret-Anne Storey&lt;/a&gt;, I studied community involvement in issue tracking in the &lt;a href="http://www.eclipse.org"&gt;Eclipse&lt;/a&gt; and &lt;a href="http://jazz.net/"&gt;IBM Jazz&lt;/a&gt; projects. IBM Jazz is a commercial IDE for collaborative development. The Jazz project has opened its issue tracking system to the Jazz community. Eclipse is a well-known open source IDE with a public issue tracking system.&lt;br /&gt;&lt;br /&gt;Our 8 page research paper "&lt;b&gt;&lt;a href="http://www.thechiselgroup.org/files/uploads/publications/grammel_eclipse_jazz_community_involvement_haose2010.pdf"&gt;Attracting the Community’s Many Eyes: an Exploration of User Involvement in Issue Tracking&lt;/a&gt;&lt;/b&gt;" was accepted at &lt;a href="http://eventseer.net/e/13696/"&gt;HAoSE 2010&lt;/a&gt;, the Second Workshop on Human Aspects of Software Engineering, co-located with &lt;a href="http://www.splashcon.org/"&gt;SPLASH 2010&lt;/a&gt;. Here is the abstract of our paper: &lt;p style="border: 1px solid darkgray; padding: 10px; background-color: rgb(242, 242, 242); padding-left: 25px;"&gt;A community of users who report bugs and request features provides valuable feedback that can be used in product development. Many open source projects provide publicly accessible issue trackers to facilitate such feedback. We compare the community involvement in issue tracker usage between the open source project Eclipse and the closed source project IBM Jazz to evaluate if publicly accessible issue trackers work as well in closed source projects. We find that IBM Jazz successfully receives user feedback through this channel. We then explore the differences in work item processing in IBM Jazz between team members, project members and externals. We conclude that making public issue trackers available in closed source projects is a useful approach for eliciting feedback from the community, but that work items created by team members are processed differently from work items created by project members and externals.&lt;/p&gt;&lt;a href="http://www.thechiselgroup.org/files/uploads/publications/grammel_eclipse_jazz_community_involvement_haose2010.pdf"&gt;Download Paper&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-618645762378228382?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/618645762378228382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=618645762378228382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/618645762378228382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/618645762378228382'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/10/attracting-communitys-many-eyes.html' title='Attracting the Community’s Many Eyes: an Exploration of User Involvement in Issue Tracking'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-5760403251295292538</id><published>2010-09-26T15:09:00.025-07:00</published><updated>2010-09-26T16:23:41.019-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='jsni'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>GWT ArrayList, HashSet and JsArray Benchmark</title><content type='html'>The performance of &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; applications varies quite a bit between the developer (hosted) mode and the compiled JavaScript code, as well as between different browsers. This blog post describes a benchmark [ &lt;a href="http://web.uvic.ca/~lgrammel/blog/gwt-benchmark/Gwt_benchmark.html"&gt;Run Benchmark&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtbenchmark"&gt;Source Code&lt;/a&gt; ] of two different collection classes (ArrayList, HashSet) in three different environments (Chrome 6, Firefox 3.5, Dev Mode). It tests the add, contains and iterator methods, and also compares the collection classes to a &lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/JsArray.java"&gt;lightweight JavaScript array wrapper&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The three benchmarks do basically the following:&lt;ul&gt;&lt;li&gt;The &lt;b&gt;add&lt;/b&gt; benchmark adds 100 items to an empty collection.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;iterator&lt;/b&gt; benchmark iterates over an collection of 100 items.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;contains&lt;/b&gt; benchmark checks if 20 items are contained in a collection of 100 items. 10 of those items are contained in the collection, and another 10 are not.&lt;/li&gt;&lt;/ul&gt;Each benchmark is run 2500 times (see &lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/GWTBenchmark.java"&gt;GWTBenchmark class&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;The results I report here are rough averages from repeated measurements (~20 times) on a Core 2 Duo 2.4 GHz machine with 4GB ram, running Windows 7 64bit and GWT 2.0.3. They should be accurate with about +/- 10% error.&lt;br /&gt;&lt;table style="width:100%; text-align: right;"&gt;&lt;tr&gt;&lt;th style="border-bottom: 1px solid gray; text-align: left; vertical-align:text-top;"&gt;&amp;nbsp;&lt;/th&gt;&lt;th style="vertical-align:text-top; border-bottom: 1px solid gray;"&gt;Chrome&lt;br/&gt;6.0.472.63 beta&lt;/th&gt;&lt;th style="vertical-align:text-top;border-bottom: 1px solid gray;"&gt;Firefox&lt;br/&gt;3.5.13&lt;/th&gt;&lt;th style="vertical-align:text-top;border-bottom: 1px solid gray;padding: 3px;"&gt;Dev Mode&lt;br/&gt;(FF 3.5.13)&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=" text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/ArrayListAddBenchmark.java"&gt;add - ArrayList&lt;/a&gt;&lt;/td&gt;&lt;td&gt;19 ms&lt;/td&gt;&lt;td&gt;550 ms&lt;/td&gt;&lt;td&gt;14 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=" text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/HashSetAddBenchmark.java"&gt;add - HashSet&lt;/a&gt;&lt;/td&gt;&lt;td&gt;200 ms&lt;/td&gt;&lt;td&gt;680 ms&lt;/td&gt;&lt;td&gt;30 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-bottom: 1px solid gray; text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/JsArrayAddBenchmark.java"&gt;add - JsArray&lt;/a&gt;&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;14 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;540 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;142000 ms&lt;/td style="border-bottom: 1px solid gray;"&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=" text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/ArrayListIteratorBenchmark.java"&gt;iterator - ArrayList&lt;/a&gt;&lt;/td&gt;&lt;td&gt;44 ms&lt;/td&gt;&lt;td&gt;395 ms&lt;/td&gt;&lt;td&gt;12 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-bottom: 1px solid gray; text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/HashSetIteratorBenchmark.java"&gt;iterator - HashSet&lt;/a&gt;&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;138 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;1220 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;8 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=" text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/ArrayListContainsBenchmark.java"&gt;contains - ArrayList&lt;/a&gt;&lt;/td&gt;&lt;td&gt;4700 ms&lt;/td&gt;&lt;td&gt;8500 ms&lt;/td&gt;&lt;td&gt;37 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=" text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/HashSetContainsBenchmark.java"&gt;contains - HashSet&lt;/a&gt;&lt;/td&gt;&lt;td&gt;23 ms&lt;/td&gt;&lt;td&gt;110 ms&lt;/td&gt;&lt;td&gt;6 ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-bottom: 1px solid gray; text-align: left;"&gt;&lt;a href="http://github.com/lgrammel/gwtbenchmark/blob/master/gwt-benchmark/src/de/larsgrammel/gwtbenchmark/client/JsArrayContainsBenchmark.java"&gt;contains - JsArray&lt;/a&gt;&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;8 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;36 ms&lt;/td&gt;&lt;td style="border-bottom: 1px solid gray;"&gt;26500 ms&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Several things can be observed based on these results:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Measuring and optimizing performance in the developer mode is useless and can be dangerous&lt;/b&gt;. The developer mode is very different from running compiled GWT code in the browser. Code that is executed only within the Java VM tends to be a lot faster. Manipulation of the DOM and calling JavaScript using JSNI, however, is much slower (see also &lt;a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html#DevGuideProdMode"&gt;GWT developer guide&lt;/a&gt;). I was surprised by the extent of this effect, for example that Java collections are up to 125 times faster than GWT compiled code on Chrome 6 (ArrayList.contains), or that JsArray.contains is 736 times faster when compiled and run on Firefox 3.5 vs. in the developer mode on Firefox 3.5.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Chrome 6 is much faster than Firefox 3.5.&lt;/b&gt; This result is pretty obvious given recent browser benchmarks. However, the differences vary depending on the collection type and operation. ArrayList.contains is surprisingly slow on Chrome 6.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The different collection classes have different advantages&lt;/b&gt;. This is also pretty obvious given their different requirements and algorithms. The HashSet is slow for add and iterate, but fast for checking the containment of items. It also assures that each element is only contained once. The ArrayList is much faster than the HashSet when calling add and iterate, but also 200 times (Chrome 6) / 77 times (Firefox 3.6)  slower when it comes to containment checks, which was surprising.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Potential speed gains when using handcrafted collection classes&lt;/b&gt;. The results for the JsArray class indicate that there is a potential for speed improvements by using &lt;a href="http://code.google.com/p/google-web-toolkit/wiki/LightweightCollections"&gt;lightweight collection classes&lt;/a&gt;. This finding is different from a &lt;a href="http://flax.ie/google-web-toolkit-javascript-vs-hand-crafted-javascript-benchmark/"&gt;benchmark that used bubble sort&lt;/a&gt;. The difference might be related to the overhead added by the GWT cross-compilation of ArrayList and HashSet.&lt;br /&gt;&lt;br /&gt;In conclusion, when having performance issues in GWT applications that use a large number of collection instances, it might be worth looking at using optimized collection classes that reduce the overhead introduced by ArrayList and HashSet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-5760403251295292538?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/5760403251295292538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=5760403251295292538' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5760403251295292538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5760403251295292538'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/09/gwt-arraylist-hashset-and-jsarray.html' title='GWT ArrayList, HashSet and JsArray Benchmark'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-4522706254810281274</id><published>2010-09-12T14:10:00.013-07:00</published><updated>2010-09-12T15:35:58.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rgba'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='window'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Combining Semi-Transparent Window Borders with Opaque Content using CSS RGBa</title><content type='html'>Developing web applications that support multiple window-like panels in a single browser page is challenging. This blog post describes how I implemented semi-transparent window borders in &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel&lt;/a&gt; to help with window resizing. I used CSS RGBa background colors to combine semi-transparent window borders with opaque window content.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/choosel/"&gt;Choosel&lt;/a&gt; is a &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; framework that aims at facilitating flexible visual data exploration. It supports multiple windows on the same page. The windows can be dynamically created, closed, moved, resized and brought to the front. Different window content types such as maps, charts &amp; notes are available. &lt;br /&gt;&lt;br /&gt;However, one of the findings from a &lt;a href="http://lgrammel.blogspot.com/2010/09/choosel-poster-at-infovis-2010.html"&gt;usability study&lt;/a&gt; was that resizing the windows was difficult. The main reason was that the window borders were fairly thin (3 pixel). So I decided to increase the border thickness to 7 pixel. However, I found that increasing the thickness of opaque borders often occluded relevant content from underneath, e.g. from other windows. To solve this problem, I implemented semi-transparent borders using CSS. The two screenshots below illustrate the differences between the two designs:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Thin, opaque borders&lt;/b&gt; &lt;i&gt;(click thumbnail to enlarge screenshot)&lt;/i&gt;&lt;br /&gt;&lt;a href="http://webhome.csc.uvic.ca/~lgrammel/2010-09-12-choosel-transparent-windows/choosel_old_windows.png"&gt;&lt;img style="border-style: none" src="http://webhome.csc.uvic.ca/~lgrammel/2010-09-12-choosel-transparent-windows/choosel_old_windows_small.png" width="510" height="397"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Thick, semi-transparent borders&lt;/b&gt; &lt;i&gt;(click thumbnail to enlarge screenshot)&lt;/i&gt;&lt;br /&gt;&lt;a href="http://webhome.csc.uvic.ca/~lgrammel/2010-09-12-choosel-transparent-windows/choosel_transparent_windows.png"&gt;&lt;img style="border-style: none" src="http://webhome.csc.uvic.ca/~lgrammel/2010-09-12-choosel-transparent-windows/choosel_transparent_windows_small.png" width="510" height="426"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A window in Choosel is basically an HTML div element that contains an HTML table. The table contains cells for the borders, the header and the content. To allow for transparent boundaries and opaque window contents at the same time, I set the background color of the window div to be completely transparent using RGBa: &lt;pre name="code" class="css"&gt;background-color: rgba(0, 0, 0, 0.0);&lt;/pre&gt; Using CSS opacity was not an option, because &lt;a href="http://www.css3.info/introduction-opacity-rgba/"&gt;opacity is inherited&lt;/a&gt; and thus combining opaque window content with transparent border would not have been easily possible. The borders have semi-transparent background colors, again set using RGBa. The transparency of the window content depends on the implementation of the content type. For example, notes are slightly semi-transparent when inactive, but the visualization views are opaque.&lt;br /&gt;&lt;br /&gt;The semi-transparent window borders were tested and work with Firefox 3.6, Chrome 6 and Safari 5. Choosel is not designed for Internet Explorer (up to version 8).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-4522706254810281274?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/4522706254810281274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=4522706254810281274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4522706254810281274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4522706254810281274'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/09/combining-semi-transparent-window.html' title='Combining Semi-Transparent Window Borders with Opaque Content using CSS RGBa'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-6905529357221757460</id><published>2010-09-10T16:03:00.006-07:00</published><updated>2010-09-10T16:37:28.328-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>Controlling the Z-Index of Map Overlays using the Google Maps Library for GWT</title><content type='html'>&lt;a href="http://maps.google.com"&gt;Google Maps&lt;/a&gt; is a great way to show location-based data on a map. In &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel&lt;/a&gt;, we implemented a generic map widget which leverages Google Maps. This can for example be used to visualize the locations of recent earthquakes. Choosel also supports multiple coordinated view with selections and highlighting of items across different views (see Video):&lt;br /&gt;&lt;br /&gt;&lt;object width="517" height="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Oz4uV6a7__0?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&amp;amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Oz4uV6a7__0?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&amp;amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="517" height="480"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;However, &lt;b&gt;occlusion in the map becomes a problem when trying to highlight resources across views&lt;/b&gt;. For example, when highlighting a particular earthquake in the timeline, it might be hidden by other earthquake overlays which are displayed on top of it in the map. The z-index of the earthquake overlay in the map would need to be adjusted such that the earthquake is displayed on top while being highlighted, but this is not directly possible using the &lt;a href="http://code.google.com/p/gwt-google-apis/wiki/MapsGettingStarted"&gt;Google Maps API 1.0 for GWT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;I implemented a custom Overlay class that uses a GWT label to display a data item&lt;/b&gt;. Using a GWT widget in the custom overlay has several advantages: (1) we can change the CSS styling, including the z-index, (2) we can use standard GWT event handlers, and (3) we don’t need to load images. &lt;br /&gt;&lt;br /&gt;Before, we used the MapIconMaker from the &lt;a href="http://code.google.com/p/gmaps-utility-library-dev/"&gt;gmaps utility library&lt;/a&gt;. The CSS based approach has some cross-browser limitation, e.g. rounded corner on IE, but it is faster because no images are loaded any more. However, the z-index changes outlined here are possible with any GWT widget, so switching to an Image widget should be easy.&lt;br /&gt;&lt;br /&gt;This are the main elements of the &lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel/src/org/thechiselgroup/choosel/client/views/map/LabelOverlay.java?spec=svn372&amp;r=281"&gt;LabelOverlay&lt;/a&gt; implementation used in Choosel:&lt;pre name="code" class="java"&gt;public class LabelOverlay extends Overlay {&lt;br /&gt;&lt;br /&gt;    private Label label;&lt;br /&gt;&lt;br /&gt;    private LatLng latLng;&lt;br /&gt;&lt;br /&gt;    private MapWidget map;&lt;br /&gt;&lt;br /&gt;    private Point offset;&lt;br /&gt;&lt;br /&gt;    private MapPane pane;&lt;br /&gt;&lt;br /&gt;    private Point locationPoint;&lt;br /&gt;&lt;br /&gt;    public LabelOverlay(LatLng latLng, Point offset, &lt;br /&gt;            String text, String styleName) {&lt;br /&gt;&lt;br /&gt;        this.latLng = latLng;&lt;br /&gt;        this.offset = offset;&lt;br /&gt;        this.label = new Label(text);&lt;br /&gt;        this.label.setStyleName(styleName);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public HandlerRegistration addClickHandler(&lt;br /&gt;            ClickHandler handler) {&lt;br /&gt;            &lt;br /&gt;        return label.addClickHandler(handler);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // ... other mouse handlers (down, move etc.)&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected final Overlay copy() {&lt;br /&gt;        return new LabelOverlay(latLng, offset, &lt;br /&gt;                label.getText(), label.getStyleName());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected final void initialize(MapWidget map) {&lt;br /&gt;        this.map = map;&lt;br /&gt;&lt;br /&gt;        pane = map.getPane(MapPaneType.MARKER_PANE);&lt;br /&gt;        pane.add(label);&lt;br /&gt;&lt;br /&gt;        updatePosition(&lt;br /&gt;            map.convertLatLngToDivPixel(latLng));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected final void redraw(boolean force) {&lt;br /&gt;        /*&lt;br /&gt;         * We check if the location has changed, because &lt;br /&gt;         * Google Maps allows infinite panning along the &lt;br /&gt;         * east-west-axis and requires an updated widget &lt;br /&gt;         * location in this case, although it will not &lt;br /&gt;         * force redrawing.&lt;br /&gt;         */&lt;br /&gt;        Point newLocationPoint = &lt;br /&gt;            map.convertLatLngToDivPixel(latLng);&lt;br /&gt;&lt;br /&gt;        if (!force &lt;br /&gt;                &amp;amp;&amp;amp; sameLocation(newLocationPoint)) {&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        updatePosition(newLocationPoint);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected final void remove() {&lt;br /&gt;        label.removeFromParent();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private boolean sameLocation(Point newLocationPoint) {&lt;br /&gt;        assert newLocationPoint != null;&lt;br /&gt;        return locationPoint != null&lt;br /&gt;                &amp;amp;&amp;amp; locationPoint.getX() &lt;br /&gt;                    == newLocationPoint.getX()&lt;br /&gt;                &amp;amp;&amp;amp; locationPoint.getY() &lt;br /&gt;                    == newLocationPoint.getY();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setZIndex(int zIndex) {&lt;br /&gt;        // CSS is a class in Choosel&lt;br /&gt;        CSS.setZIndex(label, zIndex);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // ... other CSS attribute setters&lt;br /&gt;&lt;br /&gt;    private void updatePosition(Point newLocationPoint) {&lt;br /&gt;        assert newLocationPoint != null;&lt;br /&gt;        locationPoint = newLocationPoint;&lt;br /&gt;        pane.setWidgetPosition(label, &lt;br /&gt;                locationPoint.getX() + offset.getX(),&lt;br /&gt;                locationPoint.getY() + offset.getY());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;The code uses some convenience methods from the &lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel/src/org/thechiselgroup/choosel/client/ui/CSS.java?spec=svn369&amp;r=363"&gt;Choosel CSS library class&lt;/a&gt;. The overlay are styled by default using this CSS class:&lt;pre name="code" class="css"&gt;.resourceItemIcon {&lt;br /&gt; width: 16px;&lt;br /&gt; height: 16px;&lt;br /&gt; border: 1px solid darkgray;&lt;br /&gt; text-align:center;&lt;br /&gt; vertical-align:middle;&lt;br /&gt; font-weight:bold;&lt;br /&gt; font-size: 12px; &lt;br /&gt; -moz-border-radius: 10px;&lt;br /&gt; -webkit-border-radius: 10px;&lt;br /&gt; padding: 0px; &lt;br /&gt;}&lt;/pre&gt;The rest is pretty straightforward, the overlays are created and added:&lt;pre name="code" class="java"&gt;overlay = new LabelOverlay(point, Point.newInstance(-10, -10),&lt;br /&gt;            label, CSS_RESOURCE_ITEM_ICON);&lt;br /&gt;map.addOverlay(overlay);&lt;/pre&gt;In Choosel, this functionality is distributed in the &lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel/src/org/thechiselgroup/choosel/client/views/map/MapItem.java?spec=svn369&amp;r=369"&gt;MapItem&lt;/a&gt; and &lt;a href="http://code.google.com/p/choosel/source/browse/trunk/org.thechiselgroup.choosel/src/org/thechiselgroup/choosel/client/views/map/MapViewContentDisplay.java?spec=svn369&amp;r=228"&gt;MapViewContentDisplay&lt;/a&gt; classes.&lt;br /&gt;&lt;br /&gt;Using the approach outline in this blog post, you can use GWT widgets in map overlays and control CSS attributes such as the z-Index.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-6905529357221757460?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/6905529357221757460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=6905529357221757460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6905529357221757460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6905529357221757460'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/09/controlling-z-index-of-map-overlays.html' title='Controlling the Z-Index of Map Overlays using the Google Maps Library for GWT'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-7454903190926542889</id><published>2010-09-08T13:08:00.007-07:00</published><updated>2010-09-12T15:21:40.626-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='poster'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='novice'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='publication'/><category scheme='http://www.blogger.com/atom/ns#' term='visweek'/><category scheme='http://www.blogger.com/atom/ns#' term='user study'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Choosel Poster at InfoVis 2010</title><content type='html'>I will present a poster on the &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel Framework&lt;/a&gt; at &lt;a href="http://vis.computer.org/VisWeek2010/infovis.html"&gt;IEEE InfoVis 2010&lt;/a&gt;. The main goal of the Choosel project is to enable software developers and researchers to easily create web-based visual data exploration environments for novices. The poster paper briefly summarizes some of the related work, the features of Choosel, and the results of a prelimary usability evaluation: &lt;p style="border: 1px solid darkgray; padding: 10px; background-color: rgb(242, 242, 242); padding-left: 25px;"&gt;Since information visualization has become increasingly vital to experts, it is now important to enable information visualization novices to consume, construct, and coordinate visualizations as well. Choosel is a web-based environment that aims at facilitating flexible visual data exploration for information visualization novices. It supports the iterative construction of multiple coordinated views during the visual data analysis process. A preliminary user study with 8 participants indicated that multiple windows, enhanced drag and drop interaction, and highlighting of items and sets, in particular, support novices in the visual data exploration process in a useful and intuitive way.&lt;/p&gt;&lt;a href="https://sites.google.com/site/larsgrammel/grammel_choosel_poster_2010.pdf?attredirects=0"&gt;Download Poster Abstract (2 pages)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-7454903190926542889?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/7454903190926542889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=7454903190926542889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7454903190926542889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7454903190926542889'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/09/choosel-poster-at-infovis-2010.html' title='Choosel Poster at InfoVis 2010'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-6154344986162805606</id><published>2010-09-01T16:14:00.006-07:00</published><updated>2010-09-01T16:57:18.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='novice'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Why Choosel is based on GWT</title><content type='html'>I presented &lt;a href="http://code.google.com/p/choosel/"&gt;Choosel&lt;/a&gt; to the &lt;a href="http://visid.cs.uvic.ca/"&gt;Visual Interaction Design (VisID) research group&lt;/a&gt; at the University of Victoria.  Choosel is an open-source framework for web-based information exploration environments aiming at information visualization novices. &lt;br /&gt;&lt;br /&gt;The first part of my presentation focused on several &lt;b&gt;design decision behind Choosel&lt;/b&gt;. The framework is targeting information visualization novices - those who are not familiar with information visualization and visual data analysis beyond the   graphics encountered in everyday life. Two major design decision we made based on those constraints is choosing the web as the target platform and developing Choosel using &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;We assumed that those information visualization novices are more likely to look at smaller data sets (up to 5000 items), but are not willing to spent much time getting started with visual data analysis. This was the main driver behind the decision to develop a &lt;b&gt;web-based environment&lt;/b&gt;, because this spares user the burden of installing software. We considered removing this entry barrier more important then scalability beyond several thousand data items. As our main goal was to a provide interactive information exploration environment, responsiveness was important and we decided to use primarily technology that runs on the user's computer and not on the server.&lt;br /&gt;&lt;br /&gt;In Choosel, we leverage third party visualization components and toolkits such as the &lt;a href="http://www.simile-widgets.org/timeline/"&gt;Simile Timeline&lt;/a&gt;, &lt;a href="http://vis.stanford.edu/protovis/"&gt;Protovis&lt;/a&gt; and &lt;a href="http://sourceforge.net/projects/flexviz/"&gt;FlexViz&lt;/a&gt;. In order to be able to integrate different technologies such as Flash and JavaScript in the browser, we decided to use a JavaScript based technologies. First, we developed a initial prototype using the &lt;a href="http://dojotoolkit.org/"&gt;dojo toolkit&lt;/a&gt;. However, it turned out that because of our software development skills and tool support for unit testing, refactoring, and debugging, we were able to develop the same prototype using GWT in about a quarter of the time. The current version of &lt;b&gt;Choosel is based on GWT&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Here are the slides from my presentation:&lt;br /&gt;&lt;div id="__ss_5109565"&gt;&lt;object id="__sse5109565" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelchooselvisid2010-09-01-100901175644-phpapp02&amp;rel=0&amp;stripped_title=grammel-choosel-visid20100901" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5109565" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelchooselvisid2010-09-01-100901175644-phpapp02&amp;rel=0&amp;stripped_title=grammel-choosel-visid20100901" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-6154344986162805606?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/6154344986162805606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=6154344986162805606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6154344986162805606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6154344986162805606'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/09/why-choosel-is-based-on-gwt.html' title='Why Choosel is based on GWT'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-31096021724190465</id><published>2010-07-22T17:22:00.003-07:00</published><updated>2010-11-06T14:42:50.580-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='novice'/><category scheme='http://www.blogger.com/atom/ns#' term='visweek'/><category scheme='http://www.blogger.com/atom/ns#' term='user study'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>How Information Visualization Novices Construct Visualizations</title><content type='html'>Visualization for the masses is a topic that has gained a lot of attraction in the InfoVis community in recent years, e.g. in projects such as &lt;a href="http://manyeyes.alphaworks.ibm.com/manyeyes/"&gt;IBM ManyEyes&lt;/a&gt;. The goal is to enable a wide user population to leverage information visualization technology to understand large amounts of data. This could potentially help them make more informed decisions, and is especially promising as more and more data becomes available (see &lt;a href="http://en.wikipedia.org/wiki/Open_data"&gt;open data&lt;/a&gt;). However, there are still many challenges that need to be addressed so that visualization for the masses can become a reality, ranging from limited &lt;a href="http://en.wikipedia.org/wiki/Visual_literacy"&gt;visual literacy&lt;/a&gt; to insufficient tool support.&lt;br /&gt;&lt;br /&gt;Together with &lt;a href="http://webhome.cs.uvic.ca/~mtory/"&gt;Melanie Tory&lt;/a&gt; and &lt;a href="http://webhome.cs.uvic.ca/%7Emstorey/"&gt;Margaret-Anne Storey&lt;/a&gt;, I investigated how information visualization novices construct visualizations in a laboratory setting. Our research paper "&lt;b&gt;&lt;a href="http://sites.google.com/site/larsgrammel/grammel_tr_dcs-336-ir.pdf?attredirects=0"&gt;How Information Visualization Novices Construct Visualizations&lt;/a&gt;&lt;/b&gt;" was accepted for presentation at &lt;a href="http://vis.computer.org/VisWeek2010/"&gt;IEEE InfoVis 2010&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Here is the abstract of our paper: &lt;p style="border: 1px solid darkgray; padding: 10px; background-color: rgb(242, 242, 242); padding-left: 25px;"&gt;It remains challenging for information visualization novices to rapidly construct visualizations during exploratory data analysis. We conducted an exploratory laboratory study in which information visualization novices explored fictitious sales data by communicating visualization specifications to a human mediator, who rapidly constructed the visualizations using commercial visualization software. &lt;br /&gt;&lt;br /&gt;We found that three activities were central to the iterative visualization construction process: data attribute selection, visual template selection, and visual mapping specification. The major barriers faced by the participants were translating questions into data attributes, designing visual mappings, and interpreting the visualizations. Partial specification was common, and the participants used simple heuristics and preferred visualizations they were already familiar with, such as bar, line and pie charts. &lt;br /&gt;&lt;br /&gt;From our observations, we derived abstract models that describe barriers in the data exploration process and uncovered how information visualization novices think about visualization specifications. Our findings support the need for tools that suggest potential visualizations and support iterative refinement, that provide explanations and help with learning, and that are tightly integrated into tool support for the overall visual analytics process.&lt;/p&gt;&lt;a href="http://sites.google.com/site/larsgrammel/grammel_tr_dcs-336-ir.pdf?attredirects=0"&gt;Download Technical Report&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-31096021724190465?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/31096021724190465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=31096021724190465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/31096021724190465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/31096021724190465'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/07/how-information-visualization-novices.html' title='How Information Visualization Novices Construct Visualizations'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-6118211902471206817</id><published>2010-04-19T11:53:00.003-07:00</published><updated>2010-04-19T12:00:28.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><title type='text'>Choosel Mashup Framework Available on Google Code</title><content type='html'>I released the &lt;b&gt;&lt;a href="http://code.google.com/p/choosel/"&gt;choosel mashup framework&lt;/a&gt;&lt;/b&gt; under the &lt;a href="http://www.apache.org/licenses/LICENSE-2.0.html"&gt;Apache 2.0 license&lt;/a&gt; on &lt;a href="http://code.google.com/p/choosel/"&gt;Google Code&lt;/a&gt;. It is a research prototype platform that is used in our &lt;a href="http://bio-mixer.appspot.com"&gt;Bio-Mixer&lt;/a&gt; tool, which is developed at the &lt;a href="http://www.thechiselgroup.org"&gt;CHISEL group&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Choosel supports the creation of &lt;b&gt;web-based information mashup environments&lt;/b&gt;. These mashup environments facilitate the flexible recombination of information in different views such as maps, timelines and graph viewers. Users without any programming expertise can remix information using drag and drop interaction and explore data sets. The workspaces (mashups) can be stored and shared among users.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;We are looking for contributors&lt;/b&gt;. If you are interested, please post on the &lt;a href="http://groups.google.com/group/choosel"&gt;choosel mailing list&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-6118211902471206817?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/6118211902471206817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=6118211902471206817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6118211902471206817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6118211902471206817'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/04/choosel-mashup-framework-available-on.html' title='Choosel Mashup Framework Available on Google Code'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-8828953943856221532</id><published>2010-04-14T13:14:00.007-07:00</published><updated>2010-04-18T18:01:52.515-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='poster'/><category scheme='http://www.blogger.com/atom/ns#' term='visualization'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='biomedical'/><category scheme='http://www.blogger.com/atom/ns#' term='bio-mixer'/><category scheme='http://www.blogger.com/atom/ns#' term='IBM University Days'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><category scheme='http://www.blogger.com/atom/ns#' term='user study'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='infovis'/><title type='text'>Supporting End Users in Coordinating Multiple Visualizations</title><content type='html'>As part of my PhD research, I am looking at ways to make visual data analysis more accessible to end users without data analysis expertise. Specifically, I am researching how they can easily coordinate multiple visualizations. This has led to the development of web-based visual analytics research prototype, which I evaluated in a user study. The results indicate that novel concepts such as drop target highlighting, drop previews and using multiple user defined sets are useful and easily usable for end users. &lt;br /&gt;&lt;br /&gt;I presented the tool and the results (see poster and presentation below) at the IBM University Days 2010. A version of the visual analytics environment that is tailored to exploring biomedical ontologies is available at: &lt;b&gt;&lt;a href="http://bio-mixer.appspot.com"&gt;bio-mixer.appspot.com&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px" id="__ss_3725882"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/lgrammel/poster-web-based-visual-analytics-environment-for-nonexpert-analysts" title="Poster &amp;quot;Web-based Analytics with Multiple Coordinated Visualizations&amp;quot;"&gt;Poster &amp;quot;Web-based Analytics with Multiple Coordinated Visualizations&amp;quot;&lt;/a&gt;&lt;/strong&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=posterweb-basedvisualanalyticsenvironmentfornon-expertanalysts-100414145221-phpapp02&amp;stripped_title=poster-web-based-visual-analytics-environment-for-nonexpert-analysts" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=posterweb-basedvisualanalyticsenvironmentfornon-expertanalysts-100414145221-phpapp02&amp;stripped_title=poster-web-based-visual-analytics-environment-for-nonexpert-analysts" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="width:425px" id="__ss_3725880"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/lgrammel/grammel-presentation-webbasedmashups2010" title="A web-based environment for visual client side mashups"&gt;Presentation "A web-based environment for visual client side mashups"&lt;/a&gt;&lt;/strong&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelpresentationweb-based-mashups2010-100414145203-phpapp01&amp;stripped_title=grammel-presentation-webbasedmashups2010" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=grammelpresentationweb-based-mashups2010-100414145203-phpapp01&amp;stripped_title=grammel-presentation-webbasedmashups2010" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/lgrammel"&gt;Lars Grammel&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-8828953943856221532?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/8828953943856221532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=8828953943856221532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/8828953943856221532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/8828953943856221532'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/04/web-based-multiple-coordinated.html' title='Supporting End Users in Coordinating Multiple Visualizations'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-5127246085308095999</id><published>2010-04-09T20:24:00.007-07:00</published><updated>2010-04-18T18:01:58.448-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ontology'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='biomedical'/><category scheme='http://www.blogger.com/atom/ns#' term='bio-mixer'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><title type='text'>Bio-Mixer Early Research Prototype Released</title><content type='html'>I am happy to announce the early alpha release of &lt;a href="http://bio-mixer.appspot.com/"&gt;Bio-Mixer&lt;/a&gt;, a research prototype developed at the &lt;a href="http://www.thechiselgroup.org/"&gt;CHISEL group&lt;/a&gt; at the &lt;a href="http://www.uvic.ca"&gt;University of Victoria&lt;/a&gt; in collaboration with the &lt;a href="http://www.bioontology.org/"&gt;National Center of Biomedical Ontology&lt;/a&gt;. Bio-Mixer is available at:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://bio-mixer.appspot.com"&gt;bio-mixer.appspot.com&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bio-mixer.appspot.com/"&gt;Bio-Mixer&lt;/a&gt; is a web-based environment that supports the &lt;b&gt;flexible exploration of biomedical ontologies&lt;/b&gt;. The concepts in the ontologies and their mappings can be explored in different views such as graph views, lists and timeline views. &lt;b&gt;Drag-and-drop interaction&lt;/b&gt; can be used to show items and collections in different views, to create filtered views and to synchronize selections. Bio-Mixer enhances drag and drop with a new &lt;b&gt;drop target highlighting and preview&lt;/b&gt; approach to make working with multiple collections and views easy. Bio-Mixer also provides support for ontology annotation and &lt;b&gt;workspace sharing between collaborators&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bio-Mixer Overview&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/OeVpfx92Oo0&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/OeVpfx92Oo0&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bio-Mixer Features in Detail&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/p/C67C71F54B5E198B&amp;amp;hl=en_US&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/p/C67C71F54B5E198B&amp;amp;hl=en_US&amp;amp;fs=1" type="application/x-shockwave-flash" width="480" height="385" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-5127246085308095999?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/5127246085308095999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=5127246085308095999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5127246085308095999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5127246085308095999'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/04/bio-mixer-biomedical-ontology-mashup.html' title='Bio-Mixer Early Research Prototype Released'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-1435708840202445298</id><published>2010-03-18T23:23:00.015-07:00</published><updated>2010-09-25T17:26:03.961-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='event'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt2swf'/><category scheme='http://www.blogger.com/atom/ns#' term='handler'/><category scheme='http://www.blogger.com/atom/ns#' term='external interface'/><category scheme='http://www.blogger.com/atom/ns#' term='notification'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='jsni'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='listener'/><title type='text'>Handling Flex Events in GWT</title><content type='html'>Tightly integrating &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; components in &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; applications requires that GWT is notified on events triggered in Flex. For example, when the user performs an action in the Flex component, e.g. double-clicking a node in a graph widget, we might want to perform some operations on the GWT side, e.g. updating a dependent view to show information about the double-clicked node. This tutorial shows how UI event from Flex can be forward to and handled by GWT code. The example contains a GWT text box and a Flex text box and buttons for copying the text from one to the other. This tutorial is the third part of a series of blog posts about using Flex components in GWT with the library &lt;a href="http://sourceforge.net/projects/gwt2swf/"&gt;gwt2swf&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://lgrammel.blogspot.com/2010/02/i-am-working-on-project-that-integrates.html"&gt;GWT Wrapper for Flex components&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://lgrammel.blogspot.com/2010/02/notifying-gwt-when-flex-widget-is.html"&gt;Notifying GWT when a Flex widget is loaded&lt;/a&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/notifying-gwt-when-flex-widget-is/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/notifying-gwt-when-flex-widget-is"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;3. &lt;b&gt;Handling Flex events in GWT&lt;/b&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/handling-flex-events-in-gwt/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/handling-flex-events-in-gwt"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;This tutorial is based on the previous one, notifying GWT when a Flex widget is loaded, and assumes that you have a similar project setup and that you have created the classes and files with the source code from that tutorial. The main ideas are similar those from the previous tutorial, but we will explicitly register our event handler bridge as a callback in Flex. That way, the Flex component can expose operations that might not be used by our GWT application, but in other applications, e.g. separate JavaScript projects, without requiring the GWT wrapper to provide hooks for those operations.&lt;br /&gt;&lt;br /&gt;The Flex component is first extended by adding a 'send' button and changing the text to a text input. Then a method for adding a JavaScript method as event listener is implemented and exposed. When calling registered event listeners, the Flex components adds the content of the text field, so we can use it on the GWT side. Alternatively, one could implement and expose a method for getting the content of the Flex text field from JavaScript.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Text.mxml&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&amp;lt;mx:Button id=&amp;quot;sendButton&amp;quot; x=&amp;quot;200&amp;quot; width=&amp;quot;80&amp;quot; label=&amp;quot;Send&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;mx:TextInput id=&amp;quot;textWidget&amp;quot; x=&amp;quot;0&amp;quot; width=&amp;quot;200&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;...    &lt;br /&gt;&lt;br /&gt;public function addSendListener(jsFunctionName:String):void {&lt;br /&gt;  sendButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {&lt;br /&gt;    ExternalInterface.call(jsFunctionName, swfID, textWidget.text);       &lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;      &lt;br /&gt;private function init():void {&lt;br /&gt;...&lt;br /&gt;  addJSCallback(&amp;quot;addSendListener&amp;quot;, addSendListener);&lt;br /&gt;}&lt;/pre&gt;The complete Flex component should look like this:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Text.mxml&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx=&amp;quot;http://www.adobe.com/2006/mxml&amp;quot; &lt;br /&gt;  layout=&amp;quot;absolute&amp;quot; creationComplete=&amp;quot;init()&amp;quot;&lt;br /&gt;  backgroundColor=&amp;quot;0xffffff&amp;quot; paddingBottom=&amp;quot;0&amp;quot; paddingLeft=&amp;quot;0&amp;quot; &lt;br /&gt;  paddingRight=&amp;quot;0&amp;quot; paddingTop=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;mx:Script&amp;gt;&lt;br /&gt;    &amp;lt;![CDATA[&lt;br /&gt;    &lt;br /&gt;    import mx.events.FlexEvent;&lt;br /&gt;&lt;br /&gt;    public function displayText(text:String):void {&lt;br /&gt;      textWidget.text = text;&lt;br /&gt;    }   &lt;br /&gt;      &lt;br /&gt;    private function init():void {&lt;br /&gt;      addEventListener(FlexEvent.APPLICATION_COMPLETE, onApplicationComplete);&lt;br /&gt;      addJSCallback(&amp;quot;displayText&amp;quot;, displayText);&lt;br /&gt;      addJSCallback(&amp;quot;addSendListener&amp;quot;, addSendListener);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private function onApplicationComplete(event:FlexEvent):void {&lt;br /&gt;        callLater(function():void {&lt;br /&gt;          ExternalInterface.call(&amp;quot;_swf_application_complete&amp;quot;, swfID);&lt;br /&gt;        });&lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;    public static function addJSCallback(jsFunctionName:String, flexFunction:Function):void {&lt;br /&gt;        try {&lt;br /&gt;          if (ExternalInterface.available) {&lt;br /&gt;          ExternalInterface.addCallback(jsFunctionName, flexFunction);&lt;br /&gt;          }&lt;br /&gt;      } catch (error:SecurityError) {&lt;br /&gt;        trace(&amp;quot;Couldn&amp;#39;t add javascript callback: &amp;quot; + error);&lt;br /&gt;      }&lt;br /&gt;      } &lt;br /&gt;      &lt;br /&gt;    public function addSendListener(jsFunctionName:String):void {&lt;br /&gt;      sendButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {&lt;br /&gt;        ExternalInterface.call(jsFunctionName, swfID, textWidget.text);       &lt;br /&gt;      });&lt;br /&gt;    }&lt;br /&gt;      &lt;br /&gt;    public function get swfID():String {&lt;br /&gt;      return Application.application.parameters.swfid;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ]]&amp;gt;&lt;br /&gt;  &amp;lt;/mx:Script&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;mx:Button id=&amp;quot;sendButton&amp;quot; x=&amp;quot;200&amp;quot; width=&amp;quot;80&amp;quot; label=&amp;quot;Send&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;mx:TextInput id=&amp;quot;textWidget&amp;quot; x=&amp;quot;0&amp;quot; width=&amp;quot;200&amp;quot;/&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;/pre&gt;Now we can build the Flex project and copy the generated .swf file into the GWT project. It should be under the 'public' folder below the folder that contains the .gwt.xml file, e.g. in my case as 'src/de/larsgrammel/blog/flexgwt/public/Test.swf'.&lt;br /&gt;&lt;br /&gt;The GWT wrapper keeps track of event handler that are interested in this send event. For that purpose, we add custom event and event handler classes:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TextSentEvent.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;import com.google.gwt.event.shared.GwtEvent;&lt;br /&gt;&lt;br /&gt;public class TextSentEvent extends GwtEvent&amp;lt;TextSentEventHandler&amp;gt; {&lt;br /&gt;&lt;br /&gt;  public static final Type&amp;lt;TextSentEventHandler&amp;gt; TYPE = new Type&amp;lt;TextSentEventHandler&amp;gt;();&lt;br /&gt;&lt;br /&gt;  private SampleFlexWrapperWidget swfWidget;&lt;br /&gt;&lt;br /&gt;  private String newText;&lt;br /&gt;&lt;br /&gt;  public TextSentEvent(SampleFlexWrapperWidget swfWidget, String newText) {&lt;br /&gt;    assert swfWidget != null;&lt;br /&gt;    this.newText = newText;&lt;br /&gt;    this.swfWidget = swfWidget;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void dispatch(TextSentEventHandler handler) {&lt;br /&gt;    handler.onTextSent(this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String getNewText() {&lt;br /&gt;    return newText;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Type&amp;lt;TextSentEventHandler&amp;gt; getAssociatedType() {&lt;br /&gt;    return TYPE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public SampleFlexWrapperWidget getSWFWidget() {&lt;br /&gt;    return swfWidget;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;b&gt;TextSentEventHandler.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;public interface TextSentEventHandler extends EventHandler {&lt;br /&gt;&lt;br /&gt;  void onTextSent(TextSentEvent event);&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;Now, we add a method for registering TextSentEventHandlers to our SampleFlexWrapperWidget:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SampleFlexWrapperWidget.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;...&lt;br /&gt;&lt;br /&gt;public HandlerRegistration addTextSentEventHandler(&lt;br /&gt;    TextSentEventHandler handler) {&lt;br /&gt;&lt;br /&gt;  return addHandler(handler, TextSentEvent.TYPE);&lt;br /&gt;}&lt;/pre&gt;The next two methods forward the Flex events to the registered event handlers:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SampleFlexWrapperWidget.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;...&lt;br /&gt;&lt;br /&gt;public static void _onTextSent(String swfId, String text) {&lt;br /&gt;  swfWidgets.get(swfId).onTextSent(text);&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;private void onTextSent(String text) {&lt;br /&gt;  fireEvent(new TextSentEvent(this, text));&lt;br /&gt;}&lt;/pre&gt;Now we register the _onTextSent method as listener on the Flex component by exposing it as a JavaScript method. The GWT guide recommends that &lt;a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html#calling"&gt;Java methods should be wrapped by $entry() when exposing them as JavaScript callback points&lt;/a&gt;. We thus register our wrapped _onTextSent method as JavaScript handle once the Flex component finished loading. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;SampleFlexWrapperWidget.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;...&lt;br /&gt;&lt;br /&gt;public static void onSwfApplicationComplete(String swfId) {&lt;br /&gt;  _registerSwfListeners(swfId);&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private static native void _registerSwfListeners(String swfID) /*-{&lt;br /&gt;  var swfWidget = $doc.getElementById(swfID);&lt;br /&gt;  swfWidget.addSendListener(&amp;quot;_swf_on_text_sent&amp;quot;);&lt;br /&gt;}-*/;&lt;br /&gt;&lt;br /&gt;private static native void registerCallbackMethods() /*-{&lt;br /&gt;  $wnd._swf_on_text_sent=&lt;br /&gt;  $entry(@de.larsgrammel.blog.flexgwt.client.SampleFlexWrapperWidget::_onTextSent(Ljava/lang/String;Ljava/lang/String;));&lt;br /&gt;  ...&lt;br /&gt;}-*/;&lt;/pre&gt;Finally, we change our main code to use the new functionality of our wrapper by updating the GWT text field when the Flex component sents over new text:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;FlexGWTIntegration.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;...&lt;br /&gt;flexWidget.addTextSentEventHandler(new TextSentEventHandler() {&lt;br /&gt;  public void onTextSent(TextSentEvent event) {&lt;br /&gt;    textField.setText(event.getNewText());&lt;br /&gt;  }&lt;br /&gt;});&lt;/pre&gt;&lt;br /&gt;The complete FlexGWTIntegration and SampleFlexWrapperWidget should look like this now:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SampleFlexWrapperWidget.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;&lt;br /&gt;import pl.rmalinowski.gwt2swf.client.ui.SWFWidget;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.event.shared.HandlerRegistration;&lt;br /&gt;&lt;br /&gt;public class SampleFlexWrapperWidget extends SWFWidget {&lt;br /&gt;&lt;br /&gt;  private static Map&amp;lt;String, SampleFlexWrapperWidget&amp;gt; swfWidgets = new HashMap&amp;lt;String, SampleFlexWrapperWidget&amp;gt;();&lt;br /&gt;&lt;br /&gt;  static {&lt;br /&gt;    registerCallbackMethods();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static native void _displayText(String swfID, String text) /*-{&lt;br /&gt;    $doc.getElementById(swfID).displayText(text);&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;br /&gt;  public static void onSwfApplicationComplete(String swfId) {&lt;br /&gt;    _registerSwfListeners(swfId);&lt;br /&gt;    swfWidgets.get(swfId).fireSWFWidgetReady();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static native void _registerSwfListeners(String swfID) /*-{&lt;br /&gt;    var swfWidget = $doc.getElementById(swfID);&lt;br /&gt;    swfWidget.addSendListener(&amp;quot;_swf_on_text_sent&amp;quot;);&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;br /&gt;  private static native void registerCallbackMethods() /*-{&lt;br /&gt;    $wnd._swf_on_text_sent=&lt;br /&gt;    $entry(@de.larsgrammel.blog.flexgwt.client.SampleFlexWrapperWidget::_onTextSent(Ljava/lang/String;Ljava/lang/String;));&lt;br /&gt;    $wnd._swf_application_complete=&lt;br /&gt;    $entry(@de.larsgrammel.blog.flexgwt.client.SampleFlexWrapperWidget::onSwfApplicationComplete(Ljava/lang/String;));&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;br /&gt;  public SampleFlexWrapperWidget(int width, int height) {&lt;br /&gt;    super(&amp;quot;flexgwtintegration/Test.swf&amp;quot;, width, height);&lt;br /&gt;    addFlashVar(&amp;quot;swfid&amp;quot;, getSwfId());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public HandlerRegistration addSWFWidgetReadyHandler(&lt;br /&gt;      SWFWidgetReadyHandler handler) {&lt;br /&gt;    &lt;br /&gt;    return addHandler(handler, SWFWidgetReadyEvent.TYPE);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public HandlerRegistration addTextSentEventHandler(&lt;br /&gt;      TextSentEventHandler handler) {&lt;br /&gt;&lt;br /&gt;    return addHandler(handler, TextSentEvent.TYPE);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static void _onTextSent(String swfId, String text) {&lt;br /&gt;    swfWidgets.get(swfId).onTextSent(text);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void onTextSent(String text) {&lt;br /&gt;    fireEvent(new TextSentEvent(this, text));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void displayText(String text) {&lt;br /&gt;    _displayText(getSwfId(), text);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void fireSWFWidgetReady() {&lt;br /&gt;    fireEvent(new SWFWidgetReadyEvent(this));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void onLoad() {&lt;br /&gt;    super.onLoad();&lt;br /&gt;    SampleFlexWrapperWidget.swfWidgets.put(getSwfId(), this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void onUnload() {&lt;br /&gt;    SampleFlexWrapperWidget.swfWidgets.remove(getSwfId());&lt;br /&gt;    super.onUnload();&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;FlexGWTIntegration.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;import com.google.gwt.core.client.EntryPoint;&lt;br /&gt;import com.google.gwt.event.dom.client.ClickEvent;&lt;br /&gt;import com.google.gwt.event.dom.client.ClickHandler;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyCodes;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyUpEvent;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyUpHandler;&lt;br /&gt;import com.google.gwt.user.client.ui.Button;&lt;br /&gt;import com.google.gwt.user.client.ui.RootPanel;&lt;br /&gt;import com.google.gwt.user.client.ui.TextBox;&lt;br /&gt;&lt;br /&gt;public class FlexGWTIntegration implements EntryPoint {&lt;br /&gt;&lt;br /&gt;  public void onModuleLoad() {&lt;br /&gt;    final Button sendButton = new Button(&amp;quot;Send to Flex&amp;quot;);&lt;br /&gt;    final TextBox textField = new TextBox();&lt;br /&gt;    textField.setText(&amp;quot;from GWT&amp;quot;);&lt;br /&gt;&lt;br /&gt;    final SampleFlexWrapperWidget flexWidget = &lt;br /&gt;      new SampleFlexWrapperWidget(300, 50);&lt;br /&gt;&lt;br /&gt;    RootPanel.get().add(textField);&lt;br /&gt;    RootPanel.get().add(sendButton);&lt;br /&gt;&lt;br /&gt;    RootPanel.get().add(flexWidget);&lt;br /&gt;&lt;br /&gt;    textField.setFocus(true);&lt;br /&gt;    textField.selectAll();&lt;br /&gt;&lt;br /&gt;    class MyHandler implements ClickHandler, KeyUpHandler {&lt;br /&gt;      public void onClick(ClickEvent event) {&lt;br /&gt;        displayTextInFlex();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public void onKeyUp(KeyUpEvent event) {&lt;br /&gt;        if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {&lt;br /&gt;          displayTextInFlex();&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      private void displayTextInFlex() {&lt;br /&gt;        flexWidget.displayText(textField.getText());&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    MyHandler handler = new MyHandler();&lt;br /&gt;    sendButton.addClickHandler(handler);&lt;br /&gt;    textField.addKeyUpHandler(handler);&lt;br /&gt;&lt;br /&gt;    flexWidget.addTextSentEventHandler(new TextSentEventHandler() {&lt;br /&gt;      public void onTextSent(TextSentEvent event) {&lt;br /&gt;        textField.setText(event.getNewText());&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;This example code allows you to send text from GWT to Flex and from Flex to GWT (&lt;a href="http://web.uvic.ca/~lgrammel/blog/handling-flex-events-in-gwt/FlexGWTIntegration.html"&gt;demo&lt;/a&gt;). Together with the first two parts of this tutorial series, this should enable you to use a Flex component from GWT in a way that resembles the GWT API. There are a couple more details that I will cover in future posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-1435708840202445298?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/1435708840202445298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=1435708840202445298' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1435708840202445298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1435708840202445298'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/03/handling-flex-events-in-gwt.html' title='Handling Flex Events in GWT'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-7931528934606478964</id><published>2010-03-02T21:05:00.027-08:00</published><updated>2010-04-18T18:01:42.150-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='paper'/><category scheme='http://www.blogger.com/atom/ns#' term='choosel'/><category scheme='http://www.blogger.com/atom/ns#' term='publication'/><category scheme='http://www.blogger.com/atom/ns#' term='web2se'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><title type='text'>Mashup Environments in Software Engineering</title><content type='html'>Software developers perform different kinds of analytical activities. For example, they want to find out which code might be affected by a change, which change caused a bug or build failure, or which source code was changing in work items related to performance issues. Similarly, project managers might want to learn from the latest iteration of product development by analyzing produced artifacts, e.g. work items, source code and build results. There are many tasks in software engineering that would benefit from tools that enable the flexible and integrated analysis of information stored in different places such as issue trackers, source code repositories, and requirements documents.&lt;br /&gt;&lt;br /&gt;Together with &lt;a href="http://ctreude.ca/"&gt;Christoph Treude&lt;/a&gt; and &lt;a href="http://webhome.cs.uvic.ca/%7Emstorey/"&gt;Margaret-Anne Storey&lt;/a&gt;, I outlined the idea how mashup technology can be leveraged to achieve this. Our 2 page position paper "&lt;b&gt;&lt;a href="http://sites.google.com/site/larsgrammel/web2se_mashups_author_version.pdf?attredirects=0"&gt;Mashup Environments in Software Engineering&lt;/a&gt;&lt;/b&gt;" was accepted at &lt;a href="http://sites.google.com/site/web2se/"&gt;Web2SE&lt;/a&gt;, the First Workshop on Web 2.0 for Software Engineering, co-located with &lt;a href="http://www.sbs.co.za/ICSE2010/"&gt;ICSE 2010&lt;/a&gt;. Here is the abstract of our paper: &lt;p style="border: 1px solid darkgray; padding: 10px; background-color: rgb(242, 242, 242); padding-left: 25px;"&gt;Too often, software engineering (SE) tool research is focused on&lt;br /&gt;creating  small,  stand-alone  tools  that  address  rarely  understood&lt;br /&gt;developer needs. We believe that research should instead provide&lt;br /&gt;developers  with  flexible  environments  and  interoperable  tools,&lt;br /&gt;and then study how developers appropriate and tailor these tools&lt;br /&gt;in practice. Although there has been some prior work on this, we&lt;br /&gt;feel that flexible tool environments for SE have not yet been fully&lt;br /&gt;explored. In particular, we propose adopting the Web 2.0 idea of&lt;br /&gt;mashups and mashup environments to support SE practitioners in&lt;br /&gt;analytic activities involving multiple information sources.&lt;/p&gt;&lt;a href="http://sites.google.com/site/larsgrammel/web2se_mashups_author_version.pdf?attredirects=0"&gt;Download Paper&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-7931528934606478964?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/7931528934606478964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=7931528934606478964' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7931528934606478964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7931528934606478964'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/03/mashup-environments-in-software.html' title='Mashup Environments in Software Engineering'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-5504486344779144441</id><published>2010-02-19T12:21:00.016-08:00</published><updated>2010-09-08T13:54:31.938-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='event'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt2swf'/><category scheme='http://www.blogger.com/atom/ns#' term='load'/><category scheme='http://www.blogger.com/atom/ns#' term='handler'/><category scheme='http://www.blogger.com/atom/ns#' term='external interface'/><category scheme='http://www.blogger.com/atom/ns#' term='notification'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='jsni'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='listener'/><title type='text'>Notifying GWT when a Flex widget is initialized</title><content type='html'>Flex .swf files can take a while to load. When using &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; components from within &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt;, this means that the GWT user interface tends to be ready while the Flex widgets are still loading. This can cause problems if we call methods on those Flex widgets before they are completely initialized. This tutorial shows how to notify GWT when a Flex widget is ready, and how to prevent the problem of calling an uninitialized Flex widget. It is the second part of a series of blog posts about using Flex components in GWT with the library &lt;a href="http://sourceforge.net/projects/gwt2swf/"&gt;gwt2swf&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://lgrammel.blogspot.com/2010/02/i-am-working-on-project-that-integrates.html"&gt;GWT Wrapper for Flex components&lt;/a&gt;&lt;br /&gt;2. &lt;b&gt;Notifying GWT when a Flex widget is loaded&lt;/b&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/notifying-gwt-when-flex-widget-is/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/notifying-gwt-when-flex-widget-is"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;3. &lt;a href="http://lgrammel.blogspot.com/2010/03/handling-flex-events-in-gwt.html"&gt;Handling Flex events in GWT&lt;/a&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/handling-flex-events-in-gwt/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/handling-flex-events-in-gwt"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;This tutorial is based on the previous one, &lt;a href="http://lgrammel.blogspot.com/2010/02/i-am-working-on-project-that-integrates.html"&gt;creating a GWT Wrapper for Flex components&lt;/a&gt;, and assumes that you have a similar project setup and that you have created the classes and files with the source code from that tutorial.&lt;br /&gt;&lt;br /&gt;The general idea is to listen for the application complete event in Flex, to forward this event to the GWT wrapper and to notify listeners on the GWT side. For this to work, the Flex widget must include it's swfID when forwarding the event to GWT, because we need to know which Flex widget should get notified on the GWT side if we have multiple Flex widgets. For some reason, the Flex application id does not seem to work for that purpose on all browsers, so we pass it in as a Flash var:&lt;br /&gt;&lt;br /&gt;1. Add &lt;code&gt;addFlashVar&lt;/code&gt; call for passing the swfid into the Flex component to the SampleFlexWrapperWidget constructor:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;addFlashVar(&amp;quot;swfid&amp;quot;, getSwfId());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The whole constructor should look like this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public SampleFlexWrapperWidget(int width, int height) {&lt;br /&gt;  super("flexgwtintegration/Test.swf", width, height);&lt;br /&gt;  addFlashVar("swfid", getSwfId());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. In the Flex component, add an accessor to that property:&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;public function get swfID():String {&lt;br /&gt;  return Application.application.parameters.swfid;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we can use the swf id within Flex. The next step is to listen for the application complete event in Flex and to forward it to GWT.&lt;br /&gt;&lt;br /&gt;3. Add the event listener for the application complete event in the init() method of our Flex widget. We use the application complete event, because we want to make sure that the widget is visible and ready (&lt;a href="http://www.wietseveenstra.nl/blog/2007/02/understanding-the-flex-application-startup-event-order/"&gt;More information on the Flex Application startup event order&lt;/a&gt;).&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;addEventListener(FlexEvent.APPLICATION_COMPLETE, onApplicationComplete);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The whole init method should look like this:&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;private function init():void {&lt;br /&gt;  addEventListener(FlexEvent.APPLICATION_COMPLETE, onApplicationComplete);&lt;br /&gt;  addJSCallback(&amp;quot;displayText&amp;quot;, displayText);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4. Add the event listener method to the Flex widget. We use &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layoutperformance_12.html"&gt;callLater&lt;/a&gt; here to make sure the widget is ready when the event is fired. The method calls the method with the javascript identifier &lt;code&gt;_swf_application_complete&lt;/code&gt;, which we will implement soon.&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;import mx.events.FlexEvent;&lt;br /&gt;&lt;br /&gt;private function onApplicationComplete(event:FlexEvent):void {&lt;br /&gt;  callLater(function():void {&lt;br /&gt;    ExternalInterface.call(&amp;quot;_swf_application_complete&amp;quot;, swfID);&lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The complete Flex widget should look like this by now:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx=&amp;quot;http://www.adobe.com/2006/mxml&amp;quot; &lt;br /&gt;layout=&amp;quot;absolute&amp;quot; creationComplete=&amp;quot;init()&amp;quot;&lt;br /&gt;backgroundColor=&amp;quot;0xffffff&amp;quot; paddingBottom=&amp;quot;0&amp;quot; paddingLeft=&amp;quot;0&amp;quot; &lt;br /&gt;paddingRight=&amp;quot;0&amp;quot; paddingTop=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;    &lt;br /&gt;import mx.events.FlexEvent;&lt;br /&gt;&lt;br /&gt;public function displayText(text:String):void {&lt;br /&gt;  textWidget.text = text;&lt;br /&gt;}   &lt;br /&gt;      &lt;br /&gt;private function init():void {&lt;br /&gt;  addEventListener(FlexEvent.APPLICATION_COMPLETE, onApplicationComplete);&lt;br /&gt;  addJSCallback(&amp;quot;displayText&amp;quot;, displayText);&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;private function onApplicationComplete(event:FlexEvent):void {&lt;br /&gt;  callLater(function():void {&lt;br /&gt;    ExternalInterface.call(&amp;quot;_swf_application_complete&amp;quot;, swfID);&lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;public static function addJSCallback(jsFunctionName:String, flexFunction:Function):void {&lt;br /&gt;  try {&lt;br /&gt;    if (ExternalInterface.available) {&lt;br /&gt;      ExternalInterface.addCallback(jsFunctionName, flexFunction);&lt;br /&gt;    }&lt;br /&gt;  } catch (error:SecurityError) {&lt;br /&gt;    trace(&amp;quot;Couldn&amp;#39;t add javascript callback: &amp;quot; + error);&lt;br /&gt;  }&lt;br /&gt;} &lt;br /&gt;      &lt;br /&gt;public function get swfID():String {&lt;br /&gt;  return Application.application.parameters.swfid;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&amp;lt;mx:Text id=&amp;quot;textWidget&amp;quot; width=&amp;quot;100%&amp;quot;/&amp;gt; &lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5. Build the Flex project and copy the generated .swf file into the GWT project. It should be under the 'public' folder below the folder that contains the .gwt.xml file, e.g. in my case as 'src/de/larsgrammel/blog/flexgwt/public/Test.swf'.&lt;br /&gt;&lt;br /&gt;That's it on the Flex side. On the GWT side, we need to keep track of the different widgets and their swf id's so we can forward the event to the right widget.&lt;br /&gt;&lt;br /&gt;6. Create a static map that enables us to find the GWT wrapper for a given swf id:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;private static Map&amp;lt;String, SampleFlexWrapperWidget&amp;gt; swfWidgets = new HashMap&amp;lt;String, SampleFlexWrapperWidget&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;7. Register the widget in the map when loaded and deregister it when unloaded:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void onLoad() {&lt;br /&gt;  super.onLoad();&lt;br /&gt;  SampleFlexWrapperWidget.swfWidgets.put(getSwfId(), this);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void onUnload() {&lt;br /&gt;  SampleFlexWrapperWidget.swfWidgets.remove(getSwfId());&lt;br /&gt;  super.onUnload();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we can add the methods that are called from Flex. &lt;br /&gt;&lt;br /&gt;8. Create a class initializer that calls a &lt;a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html"&gt;JSNI&lt;/a&gt; method to register the callback methods. That way, the first time one of our wrapper widgets gets created (i.e. the class is loaded), our callback method is registered.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;static {&lt;br /&gt;  registerCallbackMethods();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;9. Create the JSNI method that links a Java method to the callback point '_swf_application_complete':&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;private static native void registerCallbackMethods() /*-{&lt;br /&gt;  $wnd._swf_application_complete=&lt;br /&gt;  @de.larsgrammel.blog.flexgwt.client.SampleFlexWrapperWidget::onSwfApplicationComplete(Ljava/lang/String;);&lt;br /&gt;}-*/;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;10. Add the method that routes the event to the correct wrapper and calls fireSWFWidgetReady on that wrapper:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public static void onSwfApplicationComplete(String swfId) {&lt;br /&gt;  swfWidgets.get(swfId).fireSWFWidgetReady();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We need a special event and handler on the GWT. So lets create those and the related methods in the wrapper.&lt;br /&gt;&lt;br /&gt;11. Create SWFWidgetReadyEvent and SWFWidgetReadyHandler&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package de.larsgrammel.blog.flexgwt.client;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.event.shared.GwtEvent;&lt;br /&gt;&lt;br /&gt;public class SWFWidgetReadyEvent extends GwtEvent&amp;lt;SWFWidgetReadyHandler&amp;gt; {&lt;br /&gt;&lt;br /&gt;  public static final Type&amp;lt;SWFWidgetReadyHandler&amp;gt; TYPE = new Type&amp;lt;SWFWidgetReadyHandler&amp;gt;();&lt;br /&gt;&lt;br /&gt;  private SampleFlexWrapperWidget swfWidget;&lt;br /&gt;&lt;br /&gt;  public SWFWidgetReadyEvent(SampleFlexWrapperWidget swfWidget) {&lt;br /&gt;    assert swfWidget != null;&lt;br /&gt;    this.swfWidget = swfWidget;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void dispatch(SWFWidgetReadyHandler handler) {&lt;br /&gt;    handler.onSWFWidgetReady(this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public Type&amp;lt;SWFWidgetReadyHandler&amp;gt; getAssociatedType() {&lt;br /&gt;    return TYPE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public SampleFlexWrapperWidget getSWFWidget() {&lt;br /&gt;    return swfWidget;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package de.larsgrammel.blog.flexgwt.client;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.event.shared.EventHandler;&lt;br /&gt;&lt;br /&gt;public interface SWFWidgetReadyHandler extends EventHandler {&lt;br /&gt;&lt;br /&gt;  void onSWFWidgetReady(SWFWidgetReadyEvent event);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;12. Add a method to register a SWFWidgetReadyHandler in the wrapper class - make sure to return the HandlerRegistration so the&lt;br /&gt;listener can be remove if needed:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public HandlerRegistration addSWFWidgetReadyHandler(&lt;br /&gt;  SWFWidgetReadyHandler handler) {&lt;br /&gt;&lt;br /&gt;  return addHandler(handler, SWFWidgetReadyEvent.TYPE);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;13. Implement the fireSWFWidgetReady method:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;private void fireSWFWidgetReady() {&lt;br /&gt;  fireEvent(new SWFWidgetReadyEvent(this));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The whole SampleFlexWrapperWidget should look similar to this by now:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package de.larsgrammel.blog.flexgwt.client;&lt;br /&gt;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;&lt;br /&gt;import pl.rmalinowski.gwt2swf.client.ui.SWFWidget;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.event.shared.HandlerRegistration;&lt;br /&gt;&lt;br /&gt;public class SampleFlexWrapperWidget extends SWFWidget {&lt;br /&gt;&lt;br /&gt;  private static Map&amp;lt;String, SampleFlexWrapperWidget&amp;gt; swfWidgets = new HashMap&amp;lt;String, SampleFlexWrapperWidget&amp;gt;();&lt;br /&gt;&lt;br /&gt;  static {&lt;br /&gt;    registerCallbackMethods();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static native void _displayText(String swfID, String text) /*-{&lt;br /&gt;    $doc.getElementById(swfID).displayText(text);&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;br /&gt;  public static void onSwfApplicationComplete(String swfId) {&lt;br /&gt;    swfWidgets.get(swfId).fireSWFWidgetReady();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static native void registerCallbackMethods() /*-{&lt;br /&gt;    $wnd._swf_application_complete=&lt;br /&gt;    @de.larsgrammel.blog.flexgwt.client.SampleFlexWrapperWidget::onSwfApplicationComplete(Ljava/lang/String;);&lt;br /&gt;  }-*/;&lt;br /&gt;&lt;br /&gt;  public SampleFlexWrapperWidget(int width, int height) {&lt;br /&gt;    super(&amp;quot;flexgwtintegration/Test.swf&amp;quot;, width, height);&lt;br /&gt;    addFlashVar(&amp;quot;swfid&amp;quot;, getSwfId());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public HandlerRegistration addSWFWidgetReadyHandler(&lt;br /&gt;      SWFWidgetReadyHandler handler) {&lt;br /&gt;    return addHandler(handler, SWFWidgetReadyEvent.TYPE);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void displayText(String text) {&lt;br /&gt;    _displayText(getSwfId(), text);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void fireSWFWidgetReady() {&lt;br /&gt;    fireEvent(new SWFWidgetReadyEvent(this));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void onLoad() {&lt;br /&gt;    super.onLoad();&lt;br /&gt;    SampleFlexWrapperWidget.swfWidgets.put(getSwfId(), this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void onUnload() {&lt;br /&gt;    SampleFlexWrapperWidget.swfWidgets.remove(getSwfId());&lt;br /&gt;    super.onUnload();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;14. In the client code that uses the widget, we can now disable our control widgets by default and then enable them once the Flex widgets are ready:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;nameField.setEnabled(false);&lt;br /&gt;sendButton.setEnabled(false);&lt;br /&gt;  &lt;br /&gt;flexWidget.addSWFWidgetReadyHandler(new SWFWidgetReadyHandler() {&lt;br /&gt;  @Override&lt;br /&gt;  public void onSWFWidgetReady(SWFWidgetReadyEvent event) {&lt;br /&gt;    nameField.setEnabled(true);&lt;br /&gt;    sendButton.setEnabled(true);&lt;br /&gt;  }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I refactored the client code a bit. It now adds two similar Flex wrappers including controls by calling a addFlexWidgetAndGWTControls method. I also removed the automatic text focus - you would need to decide for one of those controls to get the focus for this to work properly. The client code looks like this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package de.larsgrammel.blog.flexgwt.client;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.core.client.EntryPoint;&lt;br /&gt;import com.google.gwt.event.dom.client.ClickEvent;&lt;br /&gt;import com.google.gwt.event.dom.client.ClickHandler;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyCodes;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyUpEvent;&lt;br /&gt;import com.google.gwt.event.dom.client.KeyUpHandler;&lt;br /&gt;import com.google.gwt.user.client.ui.Button;&lt;br /&gt;import com.google.gwt.user.client.ui.RootPanel;&lt;br /&gt;import com.google.gwt.user.client.ui.TextBox;&lt;br /&gt;&lt;br /&gt;public class FlexGWTIntegration implements EntryPoint {&lt;br /&gt;&lt;br /&gt;  public void onModuleLoad() {&lt;br /&gt;    addFlexWidgetAndGWTControls();&lt;br /&gt;    addFlexWidgetAndGWTControls();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void addFlexWidgetAndGWTControls() {&lt;br /&gt;    final Button sendButton = new Button(&amp;quot;Send&amp;quot;);&lt;br /&gt;    final TextBox nameField = new TextBox();&lt;br /&gt;    nameField.setText(&amp;quot;GWT User&amp;quot;);&lt;br /&gt;&lt;br /&gt;    nameField.setEnabled(false);&lt;br /&gt;    sendButton.setEnabled(false);&lt;br /&gt;&lt;br /&gt;    final SampleFlexWrapperWidget flexWidget = new SampleFlexWrapperWidget(&lt;br /&gt;      100, 50);&lt;br /&gt;&lt;br /&gt;    RootPanel.get().add(nameField);&lt;br /&gt;    RootPanel.get().add(sendButton);&lt;br /&gt;    RootPanel.get().add(flexWidget);&lt;br /&gt;&lt;br /&gt;    class MyHandler implements ClickHandler, KeyUpHandler {&lt;br /&gt;      public void onClick(ClickEvent event) {&lt;br /&gt;        displayTextInFlex();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public void onKeyUp(KeyUpEvent event) {&lt;br /&gt;        if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {&lt;br /&gt;          displayTextInFlex();&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      private void displayTextInFlex() {&lt;br /&gt;        flexWidget.displayText(nameField.getText());&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Add a handler to send the name to the server&lt;br /&gt;    MyHandler handler = new MyHandler();&lt;br /&gt;    sendButton.addClickHandler(handler);&lt;br /&gt;    nameField.addKeyUpHandler(handler);&lt;br /&gt;&lt;br /&gt;    flexWidget.addSWFWidgetReadyHandler(new SWFWidgetReadyHandler() {&lt;br /&gt;      @Override&lt;br /&gt;      public void onSWFWidgetReady(SWFWidgetReadyEvent event) {&lt;br /&gt;        nameField.setEnabled(true);&lt;br /&gt;        sendButton.setEnabled(true);&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this approach, your GWT controls should be disabled until the Flex widgets are completely loaded - and it should work with multiple Flex widgets. More on integrating Flex and GWT will be covered in future posts, so stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-5504486344779144441?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/5504486344779144441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=5504486344779144441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5504486344779144441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5504486344779144441'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/02/notifying-gwt-when-flex-widget-is.html' title='Notifying GWT when a Flex widget is initialized'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-5948175992853080735</id><published>2010-02-09T15:29:00.012-08:00</published><updated>2010-09-08T13:54:11.313-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='jsni'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt2swf'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='external interface'/><title type='text'>GWT Wrapper for Flex components</title><content type='html'>I am working on a project that integrates a &lt;a href="http://sourceforge.net/projects/flexviz/"&gt;Flex-based graph component&lt;/a&gt; into a &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; application. Using Flash / &lt;a href="http://www.adobe.com/products/flex/"&gt;Flex&lt;/a&gt; and GWT in combination is tricky when you want to call both Flash/Flex from GWT and GWT from Flash/Flex, because there are two bridges involved: the &lt;a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html"&gt;GWT Java Script Native Interface (JSNI)&lt;/a&gt; and the &lt;a href="http://www.adobe.com/livedocs/flex/3/langref/flash/external/ExternalInterface.html"&gt;Flex external interface&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This tutorial is the first part of a series of blog posts about using Flex components in GWT with the library &lt;a href="http://sourceforge.net/projects/gwt2swf/"&gt;gwt2swf&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;1. &lt;b&gt;GWT Wrapper for Flex components&lt;/b&gt;&lt;br /&gt;2. &lt;a href="http://lgrammel.blogspot.com/2010/02/notifying-gwt-when-flex-widget-is.html"&gt;Notifying GWT when a Flex widget is loaded&lt;/a&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/notifying-gwt-when-flex-widget-is/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/notifying-gwt-when-flex-widget-is"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;3. &lt;a href="http://lgrammel.blogspot.com/2010/03/handling-flex-events-in-gwt.html"&gt;Handling Flex events in GWT&lt;/a&gt; [&lt;a href="http://web.uvic.ca/~lgrammel/blog/handling-flex-events-in-gwt/FlexGWTIntegration.html"&gt;Demo&lt;/a&gt;, &lt;a href="http://github.com/lgrammel/gwtflexintegration/tree/handling-flex-events-in-gwt"&gt;Source Code&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;I will explain how to create a GWT adapter around a Flex component that enables calling Flex from GWT. The code will use the library &lt;a href="http://code.google.com/p/gwt2swf/"&gt;gwt2swf&lt;/a&gt;. This post will be pretty strait forward and matches the gwt2swf docs for most part, but will include sample GWT and Flex code. Essentially, I will create a subclass of SWFWidget (part of gwt2swf) that wraps all the Flex specifics and can be used from GWT. This approach enables the use of several swf widgets from GWT at the same time.&lt;br /&gt;&lt;br /&gt;To create a sample Flex component, I used the following steps:&lt;br /&gt;&lt;br /&gt;1. Create a new Flex Project (e.g. in &lt;a href="http://www.adobe.com/products/flex/features/flex_builder/"&gt;Flex Builder)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2. Add a creationComplete handler (here: init) to the mxml header&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&lt;br /&gt;layout="absolute"&lt;br /&gt;creationComplete="init()"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3. Remove the padding from the Flex component &amp;amp; set the background color in the mxml header&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&lt;br /&gt;layout="absolute" creationComplete="init()"&lt;br /&gt;backgroundColor="0xffffff"&lt;br /&gt;paddingBottom="0" paddingLeft="0"&lt;br /&gt;paddingRight="0" paddingTop="0"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4. Add the init method and a addJsCallback method with code that I shamelessly stole from my colleague Chris Callendar, who helped me getting this to work and who has an awesome Flex blog, &lt;a href="http://flexdevtips.blogspot.com/"&gt;http://flexdevtips.blogspot.com/&lt;/a&gt;.&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;public static function addJSCallback(jsFunctionName:String, flexFunction:Function):void {&lt;br /&gt;try {&lt;br /&gt; if (ExternalInterface.available) {&lt;br /&gt;   ExternalInterface.addCallback(jsFunctionName, flexFunction);&lt;br /&gt; }&lt;br /&gt;} catch (error:SecurityError) {&lt;br /&gt; trace("Couldn't add javascript callback: " + error);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Add a text field to the flex component as an example element. We will change the contents of the text field from GWT. The width is set to 100%, so that the widget resizes based on the surrounding HTML element. For other widgets, e.g. a table, you might want to set the height to 100% as well.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;mx:Text id="textWidget" width="100%"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. Add a displayText function and register it as a callback for JavaScript access under the name "displayText" in the init() method.&lt;br /&gt;&lt;pre name="code" class="as3"&gt;&lt;br /&gt;public function displayText(text:String):void {&lt;br /&gt;textWidget.text = text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function init():void {&lt;br /&gt;addJSCallback("displayText", displayText);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;7. The complete .mxml file should look similar to this by now:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&lt;br /&gt;layout="absolute" creationComplete="init()"&lt;br /&gt;backgroundColor="0xffffff" paddingBottom="0" paddingLeft="0"&lt;br /&gt;paddingRight="0" paddingTop="0"&amp;gt;&lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;public function displayText(text:String):void {&lt;br /&gt;textWidget.text = text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function init():void {&lt;br /&gt;addJSCallback("displayText", displayText);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static function addJSCallback(jsFunctionName:String, flexFunction:Function):void {&lt;br /&gt;try {&lt;br /&gt; if (ExternalInterface.available) {&lt;br /&gt;   ExternalInterface.addCallback(jsFunctionName, flexFunction);&lt;br /&gt; }&lt;br /&gt;} catch (error:SecurityError) {&lt;br /&gt; trace("Couldn't add javascript callback: " + error);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&amp;lt;mx:Text id="textWidget" width="100%"/&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;8. Build the Flex project and copy the generated .swf file into the GWT project. It should be under the 'public' folder below the folder that contains the .gwt.xml file, e.g. in my case as 'src/de/larsgrammel/blog/flexgwt/public/Test.swf'&lt;br /&gt;&lt;br /&gt;That's it on the Flex side. Here is the list of steps I followed on the GWT side:&lt;br /&gt;&lt;br /&gt;1. Download gwt2swf from &lt;a href="http://sourceforge.net/projects/gwt2swf/"&gt;http://sourceforge.net/projects/gwt2swf/&lt;/a&gt; (I use version 0.6.0 in the example presented here)&lt;br /&gt;&lt;br /&gt;2. Extract the gwt2swf.jar and add it project's buildpath&lt;br /&gt;&lt;br /&gt;3. Add gwt2swf to your project's .gwt.xml file:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;inherits name='pl.rmalinowski.gwt2swf.GWT2SWF' /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4. Create a subclass of SWFWidget (here: SampleFlexWrapperWidget) that sets swf file by specifying the swf source path in the constructor call. The first part of the swf source path is the module name, the rest the path below the 'public' directory including the .swf name.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public SampleFlexWrapperWidget(int width, int height) {&lt;br /&gt; super("flexgwtintegration/Test.swf", width, height);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Add a displayText method to that class as a public interface on the Java side. This method calls a private static native method that resolves the SWF DOM element and calls the exposed Flex method:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;private static native void _displayText(String swfID, String text) /*-{&lt;br /&gt; $doc.getElementById(swfID).displayText(text);&lt;br /&gt;}-*/;&lt;br /&gt;&lt;br /&gt;public void displayText(String text) {&lt;br /&gt; _displayText(getSwfId(), text);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. The wrapper should look similar to this by now:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class SampleFlexWrapperWidget extends SWFWidget {&lt;br /&gt;&lt;br /&gt;private static native void _displayText(String swfID, String text) /*-{&lt;br /&gt; $doc.getElementById(swfID).displayText(text);&lt;br /&gt;}-*/;&lt;br /&gt;&lt;br /&gt;public SampleFlexWrapperWidget(int width, int height) {&lt;br /&gt; super("flexgwtintegration/Test.swf", width, height);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void displayText(String text) {&lt;br /&gt; _displayText(getSwfId(), text);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;7. The wrapper can now be used in GWT, e.g. in the entry point class:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class FlexGWTIntegration implements EntryPoint {&lt;br /&gt;&lt;br /&gt;public void onModuleLoad() {&lt;br /&gt; final Button sendButton = new Button("Send");&lt;br /&gt; final TextBox nameField = new TextBox();&lt;br /&gt; nameField.setText("GWT User");&lt;br /&gt;&lt;br /&gt; final SampleFlexWrapperWidget flexWidget1 = new SampleFlexWrapperWidget(100, 50);&lt;br /&gt; final SampleFlexWrapperWidget flexWidget2 = new SampleFlexWrapperWidget(100, 50);&lt;br /&gt;&lt;br /&gt; RootPanel.get().add(nameField);&lt;br /&gt; RootPanel.get().add(sendButton);&lt;br /&gt;&lt;br /&gt; RootPanel.get().add(flexWidget1);&lt;br /&gt; RootPanel.get().add(flexWidget2);&lt;br /&gt;&lt;br /&gt; nameField.setFocus(true);&lt;br /&gt; nameField.selectAll();&lt;br /&gt;&lt;br /&gt; class MyHandler implements ClickHandler, KeyUpHandler {&lt;br /&gt;   public void onClick(ClickEvent event) {&lt;br /&gt;     displayTextInFlex();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void onKeyUp(KeyUpEvent event) {&lt;br /&gt;     if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {&lt;br /&gt;       displayTextInFlex();&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void displayTextInFlex() {&lt;br /&gt;     flexWidget1.displayText(nameField.getText());&lt;br /&gt;     flexWidget2.displayText(nameField.getText() + " 2nd version");&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; MyHandler handler = new MyHandler();&lt;br /&gt; sendButton.addClickHandler(handler);&lt;br /&gt; nameField.addKeyUpHandler(handler);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using this approach, you can use the SWF wrapper inside GWT like any other GWT widget, except for a small loading delay. I will explain how to deal with delayed loading, events from Flex and others integration issues in future blog posts - stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-5948175992853080735?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/5948175992853080735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=5948175992853080735' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5948175992853080735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/5948175992853080735'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2010/02/i-am-working-on-project-that-integrates.html' title='GWT Wrapper for Flex components'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-6962588268471631680</id><published>2009-12-10T11:45:00.005-08:00</published><updated>2010-02-09T16:21:38.514-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nomad pim'/><title type='text'>Stopping development on Nomad PIM</title><content type='html'>I will stop contributing to &lt;a href="http://nomadpim.sourceforge.net/"&gt;Nomad PIM.&lt;/a&gt; It took me a long time to make this decision, but I am confident that it is the right decision for the following reasons:&lt;br /&gt;&lt;br /&gt;First and most importantly, over the last two years I did not have much time to work on Nomad PIM, and I don't think that this will change anytime in the future.&lt;br /&gt;&lt;br /&gt;Second, a strong trend towards cloud computing and keeping private data on the web has emerged over the past few years. Furthermore, the devices that are used to access that data, e.g. smart phones &amp;amp; desktop computers, are becoming more diverse. I believe that this trend is fundamental, because it is very convenient to be able to access and modify data, especially personal data such as notes and contacts, from different devices in different situations (e.g. on the bus) without the need for manual synchronization. Nomad PIM is a desktop application for notebooks and desktop computers that stores the data locally. It would need a complete rewrite to make it available as such a cloud-based application, and there would the major obstacle of providing a cloud-based service that is hard to accomplish for an open-source project.&lt;br /&gt;&lt;br /&gt;Third, &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; technology has changed since I started developing Nomad PIM in early 2005. The first version of Nomad PIM was developed for Eclipse 3.0 - now Eclipse 3.6 is under development, and Nomad PIM is based on Eclipse 3.3 (the development version is based on Eclipse 3.5). The &lt;a href="http://www.eclipse.org/modeling/"&gt;Eclipse Modeling community&lt;/a&gt; has created a very good set of technologies and tools in the meantime, especially &lt;a href="http://www.eclipse.org/modeling/emf/"&gt;EMF&lt;/a&gt;, and a major part of the framework underlying Nomad PIM would need to be changed to leverage those technologies - which is important to facilitate future development as an Eclipse application, and has been on my todo list for a long time. Unfortunately, this would require a major work investment and I never found myself having the time to do it. Furthermore, &lt;a href="http://wiki.eclipse.org/E4"&gt;e4&lt;/a&gt; is now on the horizon, which would require even further changes.&lt;br /&gt;&lt;br /&gt;As I am the main contributor to the project, this will mean the development of Nomad PIM is discontinued. If anybody is interested in taking over as project lead, please let me know by email (lars.grammel@gmail.com). I plan on using Nomad PIM for at least the next two years, and I will still be providing fixes to critical bugs. I will also provide detailed guides how to migrate your data to other services or applications (for the services / applications I migrate my data to). Please be aware that because Nomad PIM stores your data as human-readable XML files, your data is not locked in and you can use freely available tools such as XSLT processors to convert it into formats that can be imported into other services.&lt;br /&gt;&lt;br /&gt;It was a great experience developing Nomad PIM. I would like to thank all contributors, especially Frank Ganske and Philip Ritzkopf.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-6962588268471631680?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/6962588268471631680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=6962588268471631680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6962588268471631680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/6962588268471631680'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/12/stopping-development-on-nomad-pim.html' title='Stopping development on Nomad PIM'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-1231035271638016385</id><published>2009-11-03T18:53:00.006-08:00</published><updated>2009-11-09T12:15:56.686-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cascon'/><category scheme='http://www.blogger.com/atom/ns#' term='workshop'/><category scheme='http://www.blogger.com/atom/ns#' term='business intelligence'/><title type='text'>CASCON Workshop on "User Interfaces for Visual Analysis and Monitoring in Business Intelligence".</title><content type='html'>Are you interested in the future of user interfaces for business intelligence? &lt;br /&gt;&lt;br /&gt;Tomorrow (Wednesday, November 4th 2009) there is a &lt;a href="https://www-927.ibm.com/ibm/cas/cascon/index.shtml"&gt;CASCON&lt;/a&gt; workshop on "User Interfaces for Visual Analysis and Monitoring in Business Intelligence". It is co-organized by &lt;a href="http://webhome.cs.uvic.ca/~mstorey/index.html"&gt;Margaret-Anne Storey&lt;/a&gt;, &lt;a href="http://ctreude.ca/"&gt;Christoph Treude&lt;/a&gt; and myself. The workshop starts at 1pm in Markham Ballroom C. This is the agenda:&lt;br /&gt;&lt;br /&gt;1:00 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_storey_intro.pdf"&gt;Introduction&lt;/a&gt; (Margaret-Anne Storey, UVic)&lt;br /&gt;1:15 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_jou_charting.pdf"&gt;Charting and Visualization at Cognos Software&lt;/a&gt; (Stephan Jou, IBM)&lt;br /&gt;1:45 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_mcallister.ppt"&gt;Mapping the BI Visualization Landscape&lt;/a&gt; (Mike McAllister, SAP)&lt;br /&gt;2:15 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_grammel.pdf"&gt;Visualization Construction by Non-Experts&lt;/a&gt; (Lars Grammel, UVic)&lt;br /&gt;2:45 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_rayside.pdf"&gt;Visualizing higher-dimensional Pareto fronts for complex decision making&lt;/a&gt; (Derek Rayside, MIT)&lt;br /&gt;&lt;br /&gt;3:15 pm Coffee break&lt;br /&gt;&lt;br /&gt;3:30 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_treude.pdf"&gt;Dashboards in IBM's Jazz: BI for Software Development&lt;/a&gt; (Christoph Treude, UVic)&lt;br /&gt;4:00 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_jou_mobile.pdf"&gt;Business Intelligence on Mobile Devices&lt;/a&gt; (Stephan Jou, IBM Cognos)&lt;br /&gt;4:30 pm &lt;a href="http://lars.grammel.googlepages.com/cascon_2009_bi_workshop_storey_summa.pdf"&gt;Wrap-up&lt;/a&gt; (Margaret-Anne Storey, UVic)&lt;br /&gt;&lt;br /&gt;We hope to see you tomorrow!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-1231035271638016385?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/1231035271638016385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=1231035271638016385' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1231035271638016385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1231035271638016385'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/11/cascon-workshop-on-user-interfaces-for.html' title='CASCON Workshop on &quot;User Interfaces for Visual Analysis and Monitoring in Business Intelligence&quot;.'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>33</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-1272419569005507001</id><published>2009-05-23T21:06:00.017-07:00</published><updated>2009-05-24T16:53:14.361-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='cross-domain'/><category scheme='http://www.blogger.com/atom/ns#' term='xss'/><category scheme='http://www.blogger.com/atom/ns#' term='cross-site'/><title type='text'>Cross-domain data retrieval in client-side mashups</title><content type='html'>Browsers do not allow dynamic cross-domain data retrieval to prevent &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;cross-site scripting attacks&lt;/a&gt;. However, client-based mashups need to access data sources that reside on different servers. There are several solutions to this problem: &lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.yahoo.com/javascript/howto-proxy.html"&gt;Proxies&lt;/a&gt;: requires running proxy on intermediate server, leads to slower responses and additional traffic&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.sitepen.com/blog/2008/07/22/windowname-transport/"&gt;Window.name transport&lt;/a&gt;: requires support by the accessed services, because window.name property has to be set&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html"&gt;JSON and dynamic &amp;lt;script&amp;gt; tags&lt;/a&gt;: requires that the accessed services expose JSON, which is e.g. not the case for RSS feeds (which use XML)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mozilla.org/projects/security/components/signed-scripts.html"&gt;Signed JavaScript&lt;/a&gt;: only available for Firefox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.w3.org/2006/waf/access-control/"&gt;W3C Cross-Origin Resource Sharing&lt;/a&gt;: needs support on client and accessed service side, only available for&lt;br /&gt;&lt;a href="https://developer.mozilla.org/En/HTTP_access_control"&gt;Firefox 3.5&lt;/a&gt; and Internet Explorer 8&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/crossxhr/wiki/CrossXhr"&gt;Flash drop-in&lt;/a&gt;: requires Flash on the client and a crossdomain.xml file on the server with the accessed service that support the crossdomain access.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Because all the solutions except the proxy restrict either the browsers or the web services that can be used, I decided to go with the proxy solution. I downloaded the &lt;a href="http://www.abdulqabiz.com/blog/archives/2007/05/31/php-proxy-script-for-cross-domain-requests/"&gt;PHP proxy script from Abdul Qabiz Blog&lt;/a&gt; and modified it as suggested by the comments on his blog post. I also added a small section to make sure the default content type is XML:&lt;pre name="code" class="php"&gt;&lt;br /&gt;if ($mimeType != "") {&lt;br /&gt;  // set header from mime type&lt;br /&gt;  header("Content-Type: ".$mimeType);&lt;br /&gt;} else {&lt;br /&gt;  // assume web service returns xml&lt;br /&gt;  header("Content-Type: text/xml");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The proxy script works for me in a development environment now, but I do not recommend using it in a production environment, because important features such as restrictions of the client domain and forwarding the headers from the original service response are missing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-1272419569005507001?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/1272419569005507001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=1272419569005507001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1272419569005507001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1272419569005507001'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/05/cross-domain-data-retrieval-in-client.html' title='Cross-domain data retrieval in client-side mashups'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-3831785456168501576</id><published>2009-05-23T15:14:00.009-07:00</published><updated>2009-05-23T17:39:24.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FloatingPane'/><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>Google map in dojo FloatingPane</title><content type='html'>I created a &lt;a href="http://lars.grammel.googlepages.com/example_google_maps_dojo_floatingpa.html"&gt;small example&lt;/a&gt; that shows how to run &lt;a href="http://code.google.com/apis/maps/"&gt;Google Maps&lt;/a&gt; in a &lt;a href="http://dojotoolkit.org/"&gt;dojo&lt;/a&gt; FloatingPane. It can be found &lt;a href="http://lars.grammel.googlepages.com/example_google_maps_dojo_floatingpa.html"&gt;here&lt;/a&gt;. The code has been tested with Firefox 3.0 and Internet Explorer 8.0 .&lt;br /&gt;&lt;br /&gt;The map uses the complete content canvas that is available in the FloatingPane:&lt;pre name="code" class="html"&gt;&amp;lt;div id=&amp;quot;map_container&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;div id=&amp;quot;map&amp;quot; style=&amp;quot;width:100%;height:100%;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;In the JavaScript part, a FloatingPane is created for the map_container element, the map widget is created and the resize events from the FloatingPane are forwarded to the map widget using dojo.connect: &lt;pre name="code" class="jscript"&gt;var floatingPane = createFloatingPane("map_container");&lt;br /&gt;// ... (some checks etc)&lt;br /&gt;var mapElement = dojo.byId("map");&lt;br /&gt;var map = new GMap2(mapElement);&lt;br /&gt;// ... (map configuration)&lt;br /&gt;function resize() {&lt;br /&gt;  map.checkResize();&lt;br /&gt;}&lt;br /&gt;dojo.connect(floatingPane,"resize", resize);&lt;/pre&gt;The example also has function that creates a dojox.layout.FloatingPane from a set of parameters. It contains a minor fix for some problems I had with the dragging of automatically created FloatingPane widgets in Firefox 3.0:&lt;br /&gt;&lt;pre name="code" class="jscript"&gt;function createFloatingPane(&lt;br /&gt;    divId, title, x, y, width, height) {&lt;br /&gt;&lt;br /&gt;  var pane = new dojox.layout.FloatingPane({  &lt;br /&gt;    'title': title,&lt;br /&gt;    'id': divId + "_floater",&lt;br /&gt;    'closeable': true,&lt;br /&gt;    'resizable': true,&lt;br /&gt;    'dockable': false&lt;br /&gt;  }, divId);&lt;br /&gt; &lt;br /&gt;  // quick fix for positioning, does not seem &lt;br /&gt;  // necessary in dojo source code test&lt;br /&gt;  // (FloatingPane test), but was necessary with &lt;br /&gt;  // dojo binaries and Firefox 3.0.10&lt;br /&gt;  pane.domNode.style.left = x + "px";&lt;br /&gt;  pane.domNode.style.top = y + "px";&lt;br /&gt;  pane.resize({ 'w': width, 'h': height });&lt;br /&gt;&lt;br /&gt;  pane.startup(); &lt;br /&gt; &lt;br /&gt;  return pane;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-3831785456168501576?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/3831785456168501576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=3831785456168501576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3831785456168501576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/3831785456168501576'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/05/google-map-in-dojo-floatingpane.html' title='Google map in dojo FloatingPane'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-1564481374703482094</id><published>2009-05-19T17:26:00.010-07:00</published><updated>2010-02-09T16:33:40.053-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persevere'/><category scheme='http://www.blogger.com/atom/ns#' term='ec2'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><title type='text'>Running Persevere on Amazon EC2</title><content type='html'>Today I looked into running &lt;a href="http://www.persvr.org/"&gt;Persevere&lt;/a&gt; on Amazon servers, namely using their &lt;a href="http://aws.amazon.com/ec2/"&gt;Elastic Compute Cloud (EC2)&lt;/a&gt;. Persevere is a schema-free DB with a JSON/REST interface. It also provides a web front end for easy access.&lt;br /&gt;&lt;br /&gt;I found their Amazon Web Services (AWS) Management Console pretty usable - it makes it really easy to configure the running instances, the block storage and the elastic IPs. I ran an instance with the "Basic Fedora Core 8" Amazon Machine Image (AMI). For this purpose, I also created a security group 'test'. Using this &lt;a href="http://docs.amazonwebservices.com/AmazonEC2/gsg/2006-06-26/putty.html"&gt;Putty for EC2 guide&lt;/a&gt;, I was quickly able to connect to the server using SSH.&lt;br /&gt;&lt;br /&gt;I created a 1GB elastic block storage (EBS) volume and connected it to the running EC2 instance. The EBS volumes are stored persistently, even if the EC2 instance is terminated (which means all data in the instance is lost, and it can happen due to hardware failures). Furthermore, snapshots can be taken easily using the AWS management console. To use it from the EC2 instance, the volume has to be formatted and mounted (from the SSH console):&lt;br /&gt;&lt;pre name="code" class="bash"&gt;&lt;br /&gt;mkfs -t ext3 /dev/sdf&lt;br /&gt;mkdir /mnt/volume_1&lt;br /&gt;mount /dev/sdf /mnt/volume_1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I downloaded Java &amp;amp; Persevere to the mounted volume using &lt;code&gt;wget&lt;/code&gt; and unpacked them into the &lt;code&gt;/mnt/volume_1/opt/java&lt;/code&gt; and &lt;code&gt;/mnt/volume_1/opt/persevere&lt;/code&gt; folders (&lt;a href="http://news.softpedia.com/news/How-to-Install-Java-in-Fedora-Core-6-39724.shtml"&gt;short guide for Java&lt;/a&gt;). For real-world usage, it would be better to create a customized AMI that contains &amp;amp; starts them, but I wanted to try things out quickly.&lt;br /&gt;&lt;br /&gt;Persevere started up fine (using &lt;code&gt;java -jar startup.jar&lt;/code&gt;), but port 8080 was initially blocked by the Amazon firewall. Using the AWS management console, I added an allowed connection for TCP port 8080 (both from and to) and source 0.0.0.0/0. That way, I could access the Persevere web interface (using the Public DNS of the runnning EC2 instance which is available in the management console and appending port 8080).&lt;br /&gt;&lt;br /&gt;The next step was securing the access to Persevere (note: before starting with this, I created a Persevere user from the web UI). Persevere uses &lt;a href="http://www.mortbay.org/jetty/"&gt;Jetty&lt;/a&gt;, so I tweaked a couple of settings in the Jetty configuration. First, I configured &lt;a href="http://docs.codehaus.org/display/JETTY/How+to+configure+SSL"&gt;Jetty to use HTTP over SSL&lt;/a&gt;. Then I set up the user authentification. For this, I had to &lt;a href="http://docs.codehaus.org/display/JETTY/Realms"&gt;configured a user realm &lt;/a&gt;(&lt;code&gt;HashUserRealm&lt;/code&gt;), which was pretty straightforward. I used plain passwords for testing purposes, but for more serious undertaking &lt;a href="http://docs.codehaus.org/display/JETTY/Securing+Passwords"&gt;encrypted passwords or hash sums &lt;/a&gt; and a database storage are more appropriate. After creating the user realm, I modified the Persevere &lt;code&gt;WEB-INF/web.xml&lt;/code&gt; to &lt;a href="http://docs.codehaus.org/display/JETTY/How+to+Configure+Security+with+Embedded+Jetty"&gt;restrict the access to the web UI&lt;/a&gt;. I also switched off port 8080 and modified the firewall setting in the AWS management console accordingly. After those changes (and restarting), the Persevere web UI was running on port 8443 over SSH, and required me to log in. Interestingly, I had to use the same user name and password in the user realm and the internal Persevere user, and I got signed in the Persevere web UI automatically. Logging out did not work though.&lt;br /&gt;&lt;br /&gt;I also tried out the elastic IP service, which assigns an IP to an EC2 instance. I lost the SSH connection to the EC2 instance after this, I believe it was because the IP address changed. After rebooting the EC2 instance and reconnecting to the new IP address, I had no problems (although I needed to mount the EBS volume and start Persevere again).&lt;br /&gt;&lt;br /&gt;Overall, I was pretty impressed how easy it is to set up services on EC2. Also, an initial securing of Persevere turned out to be easy. While I liked the technical side of things pretty much, EC2 is too expensive for my use case (having a private server on the web where I can deploy some customized services and programs). The instance hour of an EC2 instance is 0.10 USD - if you run your server 24/7, this is 876 USD / year, not counting data traffic and storage. If you want to do your own calculation, take a look at the &lt;a href="http://calculator.s3.amazonaws.com/calc5.html"&gt;AWS calculator&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-1564481374703482094?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/1564481374703482094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=1564481374703482094' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1564481374703482094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/1564481374703482094'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/05/running-persevere-on-amazon-ec2.html' title='Running Persevere on Amazon EC2'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-4879590491861149443</id><published>2009-05-12T15:24:00.014-07:00</published><updated>2010-02-09T16:34:05.949-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='datagrid'/><category scheme='http://www.blogger.com/atom/ns#' term='google gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><title type='text'>Using Dojo DataGrid in Google Gadget</title><content type='html'>I spent some time last week working with &lt;a href="http://code.google.com/apis/gadgets/"&gt;Google Gadgets&lt;/a&gt; and &lt;a href="http://www.dojotoolkit.org"&gt;Dojo&lt;/a&gt;. I had some trouble getting the DataGridrid running in iGoogle at first, so here is a short snippet that shows an example dojo DataGrid running in a Google Gadget.&lt;br /&gt;&lt;br /&gt;One mistake I made was calling the initialization methods without using &lt;code&gt;dojo.addOnLoad&lt;/code&gt; by registering them just as callbacks for the google onload functionality. That way, the dojo classes were not loaded as expected, which resulted in a lot of weird errors. The solution is calling &lt;code&gt;dojo.addOnLoad&lt;/code&gt; from within the callback:&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;gadgets.util.registerOnLoadHandler(function() {&lt;br /&gt;  dojo.addOnLoad(someExampleInitializationFunction);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;The complete code for the gadget (using dojo 1.3.1) is below:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;Module&amp;gt;&lt;br /&gt;&amp;lt;ModulePrefs title=&amp;quot;Dojo Grid Example&amp;quot; &lt;br /&gt;   height=&amp;quot;400&amp;quot; scrolling=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;Content type=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;&lt;br /&gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;    @import url(&amp;quot;http://ajax.googleapis.com/&lt;br /&gt;      ajax/libs/dojo/1.3.1/dojo/resources/dojo.css&amp;quot;);&lt;br /&gt;    @import url(&amp;quot;http://ajax.googleapis.com/&lt;br /&gt;      ajax/libs/dojo/1.3.1/dijit/themes/tundra/&lt;br /&gt;      tundra.css&amp;quot;);&lt;br /&gt;    @import url(&amp;quot;http://ajax.googleapis.com/&lt;br /&gt;      ajax/libs/dojo/1.3.1/dojox/grid/resources/&lt;br /&gt;      Grid.css&amp;quot;);&lt;br /&gt;    @import url(&amp;quot;http://ajax.googleapis.com/&lt;br /&gt;      ajax/libs/dojo/1.3.1/dojox/grid/resources/&lt;br /&gt;      tundraGrid.css&amp;quot;);&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&lt;br /&gt;    src=&amp;quot;http://ajax.googleapis.com/ajax/&lt;br /&gt;    libs/dojo/1.3.1/dojo/dojo.xd.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;dojo.require(&amp;quot;dojo.data.ItemFileReadStore&amp;quot;);&lt;br /&gt;dojo.require(&amp;quot;dojox.grid.DataGrid&amp;quot;);&lt;br /&gt;&lt;br /&gt;function init() {&lt;br /&gt;&lt;br /&gt; var dataItems = {&lt;br /&gt;     identifier: &amp;#39;id&amp;#39;,&lt;br /&gt;     label: &amp;#39;title&amp;#39;,&lt;br /&gt;     items: [{ &lt;br /&gt;      &amp;#39;id&amp;#39;: 0,&lt;br /&gt;      &amp;#39;title&amp;#39;: &amp;#39;This blog&amp;#39;,&lt;br /&gt;      &amp;#39;url&amp;#39;: &amp;#39;http://lgrammel.blogspot.com/&amp;#39;&lt;br /&gt;     },{ &lt;br /&gt;      &amp;#39;id&amp;#39;: 1,&lt;br /&gt;      &amp;#39;title&amp;#39;: &amp;#39;My homepage&amp;#39;,&lt;br /&gt;      &amp;#39;url&amp;#39;: &amp;#39;http://larsgrammel.de/&amp;#39;&lt;br /&gt;  }]&lt;br /&gt; };&lt;br /&gt;   &lt;br /&gt; var store = &lt;br /&gt;   new dojo.data.ItemFileReadStore({data: dataItems});&lt;br /&gt;   &lt;br /&gt; var structure = [{&lt;br /&gt;     cells: [{&lt;br /&gt;       field: &amp;#39;title&amp;#39;, &lt;br /&gt;       name: &amp;#39;Title&amp;#39;, &lt;br /&gt;       width: &amp;#39;auto&amp;#39; &lt;br /&gt;     }, {&lt;br /&gt;       field: &amp;#39;url&amp;#39;, &lt;br /&gt;       name: &amp;#39;Address&amp;#39;, &lt;br /&gt;       width: &amp;#39;auto&amp;#39; &lt;br /&gt;     }]&lt;br /&gt; }];  &lt;br /&gt;   &lt;br /&gt; var grid = new dojox.grid.DataGrid({&lt;br /&gt;  &amp;#39;store&amp;#39;: store,&lt;br /&gt;  &amp;#39;structure&amp;#39;: structure&lt;br /&gt; }, &amp;#39;gridNode&amp;#39;);&lt;br /&gt;&lt;br /&gt; grid.startup();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;gadgets.util.registerOnLoadHandler(function() {&lt;br /&gt; dojo.addOnLoad(init);&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id=&amp;quot;gridNode&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/Content&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Module&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-4879590491861149443?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/4879590491861149443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=4879590491861149443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4879590491861149443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4879590491861149443'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/05/version-encoding-title-grid-example.html' title='Using Dojo DataGrid in Google Gadget'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-4538159300330056390</id><published>2009-02-02T11:48:00.011-08:00</published><updated>2010-02-09T16:34:52.121-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iWidget'/><category scheme='http://www.blogger.com/atom/ns#' term='IBM Mashup Center'/><category scheme='http://www.blogger.com/atom/ns#' term='iContext'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><title type='text'>iWidgets: Referring to iContext from innerHTML</title><content type='html'>Recently, I started creating some widgets for &lt;a href="http://www-01.ibm.com/software/info/mashup-center/"&gt;IBM mashup center&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For HTML that is added in the iw:content section of the iWidget xml file, the iContext can used to access the widget functionality:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;iw:content mode=&amp;quot;view&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;![CDATA[&lt;br /&gt;  &amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;input type=&amp;quot;button&amp;quot; value=&amp;quot;update settings&amp;quot; &lt;br /&gt;     onclick=&amp;quot;iContext.iScope().updateSettings();&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;]]&amp;gt;&lt;br /&gt;&amp;lt;/iw:content&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, that does not work if you generate the HTML from inside the javascript and use innnerHTML to insert it into the iWidget. For example, the&lt;br /&gt;following code leads to the javascript error "iContext is not defined".&lt;br /&gt;&lt;pre name="code" class="js"&gt;var node = this.iContext.getElementById(&amp;quot;main&amp;quot;);&lt;br /&gt;var html = '&amp;lt;input type=&amp;quot;button&amp;quot; value=&amp;quot;update settings&amp;quot;';&lt;br /&gt;html += 'onclick=&amp;quot;iContext.iScope().updateSettings();&amp;quot;/&amp;gt;';&lt;br /&gt;node.innerHTML = html;&lt;/pre&gt;&lt;br /&gt;The reason for this problem is that Mashup Center rewrites the iContext calls from HTML and replaces iContext with the concrete iContext for the widget (something similar to _ns_0643e0a0e66511ddbf33c9dc98c8dde1_iContext, with the ID of the current widget).&lt;br /&gt;&lt;br /&gt;To work around this problem, this identifier has to be used instead of iContext when creating HTML with iContext calls from javascript. The following function returns the complete, resolved iContext identifier:&lt;br /&gt;&lt;pre name="code" class="js"&gt;getCompleteiContextIdentifier : function() {&lt;br /&gt;    return &amp;quot;_&amp;quot; + this.iContext.widgetId + &amp;quot;_iContext&amp;quot;;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Using this function, the fixed version of the javascript from above would be the following:&lt;br /&gt;&lt;pre name="code" class="js"&gt;var node = this.iContext.getElementById(&amp;quot;main&amp;quot;);&lt;br /&gt;var html = '&amp;lt;input type=&amp;quot;button&amp;quot; value=&amp;quot;update settings&amp;quot;';&lt;br /&gt;html += 'onclick=&amp;quot;' + this.getCompleteiContextIdentifier();&lt;br /&gt;html += '.iScope().updateSettings();&amp;quot;/&amp;gt;';&lt;br /&gt;node.innerHTML = html;&lt;/pre&gt;&lt;br /&gt;This code was tested with IBM Mashup Center 1.1. I don't know if the same problem exists in other versions of Mashup Center.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-4538159300330056390?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/4538159300330056390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=4538159300330056390' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4538159300330056390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/4538159300330056390'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2009/02/iwidgets-referring-to-icontext-from.html' title='iWidgets: Referring to iContext from innerHTML'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-8965326499658577956</id><published>2008-05-29T09:58:00.006-07:00</published><updated>2010-03-02T21:45:41.570-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='paper'/><category scheme='http://www.blogger.com/atom/ns#' term='publication'/><category scheme='http://www.blogger.com/atom/ns#' term='writing'/><title type='text'>Configuring Eclipse for Writing Papers</title><content type='html'>I used to write my papers in Latex using Kile (a KDE Latex IDE) - but several limitations like having to use external tools for versioning, missing integrated literature management and limited extendibility made me look for an alternative solution. &lt;br /&gt;&lt;br /&gt;Being an Eclipse user &amp; RCP developer, I immediately though of customizing Eclipse for writing scientific publications aka papers. Here is a short description of the configuration I currently use:&lt;br /&gt;&lt;br /&gt;Programs / Plugins&lt;br /&gt;- &lt;a href="http://www.eclipse.org/downloads/packages/"&gt;Eclipse 3.4&lt;/a&gt; as baseline&lt;br /&gt;- &lt;a href="http://texlipse.sourceforge.net/"&gt;TexClipse&lt;/a&gt; for writing Latex&lt;br /&gt;- &lt;a href="http://eclipsewiki.sourceforge.net/"&gt;EclipseWiki&lt;/a&gt; for writing notes on read literature using a wiki style in the workspace&lt;br /&gt;- A local &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; server for versioning my changes&lt;br /&gt;- &lt;a href="http://www.eclipse.org/subversive/"&gt;Subversive&lt;/a&gt; for connecting to subversion&lt;br /&gt;&lt;br /&gt;General Configuration&lt;br /&gt;- file association (under Preferences) *.bib to my favorite bibliography tool (KBibTex)&lt;br /&gt;- file association *.pdf to preferred PDF viewer&lt;br /&gt;- Wiki settings to use TWiki (Preferences/Wiki/Rendering) for historical reasons&lt;br /&gt;&lt;br /&gt;Subversion / Workspace layout&lt;br /&gt;- no trunk/branches/tags, just plain project name (I believe that this is not necessary because typical publications do not require branching etc. as far as I see it)&lt;br /&gt;- for each publication I write, I have a separate project, e.g. paper_conferenceA_2008&lt;br /&gt;- there is a bibliography project with the bibliography.bib file used by all projects (by \bibliography{../bibliography/bibliography} - when I finish a paper I copy the current bibliography to that project and change the reference to the copy (to it from breaking in the future))&lt;br /&gt;- in the bibliography project, I have a literature folder containing .wiki (notes) and .pdf (paper itself) files for the papers I read. That way, I can search my notes and find the papers. The name for both is firstauthorname_yearX, X being a,b,c... depending on the number of publications from that author in that year.&lt;br /&gt;&lt;br /&gt;Project configuration&lt;br /&gt;- Latex Project Properties/temporary files directory: tmp (excluded in subversion)&lt;br /&gt;- output as DVI&lt;br /&gt;&lt;br /&gt;The advantages of using such a configuration are:&lt;br /&gt;- if you are used to Eclipse, you can rely on this knowledge (e.g. shortcuts)&lt;br /&gt;- integrated versioning support&lt;br /&gt;- notes, papers, and bibliography at one place&lt;br /&gt;- opportunity to develop additional tooling (visualizations, search, etc.)&lt;br /&gt;- mostly platform independent&lt;br /&gt;&lt;br /&gt;I might have missed some details of my configuration - if you notice something not quite working or unclear, please comment on this post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-8965326499658577956?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/8965326499658577956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=8965326499658577956' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/8965326499658577956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/8965326499658577956'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2008/05/configuring-eclipse-for-writing-papers.html' title='Configuring Eclipse for Writing Papers'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6639026537345948621.post-7932691957905457816</id><published>2007-03-31T06:44:00.002-07:00</published><updated>2008-05-29T09:54:26.702-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><title type='text'>Producing  Open Source Software</title><content type='html'>How to Run a Successful Free Software Project&lt;br /&gt;&lt;br /&gt;&lt;a href="http://producingoss.com/"&gt;http://producingoss.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6639026537345948621-7932691957905457816?l=lgrammel.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lgrammel.blogspot.com/feeds/7932691957905457816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6639026537345948621&amp;postID=7932691957905457816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7932691957905457816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6639026537345948621/posts/default/7932691957905457816'/><link rel='alternate' type='text/html' href='http://lgrammel.blogspot.com/2007/03/producing-open-source-software.html' title='Producing  Open Source Software'/><author><name>lgrammel</name><uri>http://www.blogger.com/profile/09802741785717077341</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_vBNKMncS67Y/St3vch8jyJI/AAAAAAAAAUw/uNsG0SGogxU/S220/lg_140x185.jpg'/></author><thr:total>0</thr:total></entry></feed>
