<?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-1872922649370966015</id><updated>2012-01-27T00:46:13.498-08:00</updated><category term='domain model'/><category term='visual'/><category term='Commands'/><category term='GRAPS'/><category term='courses'/><category term='use cases'/><category term='commandParameter'/><category term='java courses'/><category term='Cape Town'/><category term='oo analysis'/><category term='development'/><category term='junit'/><category term='Actions'/><category term='annotations'/><category term='UI'/><category term='spin'/><category term='conference'/><category term='validation'/><category term='GUI'/><category term='IAction'/><category term='gryphon'/><category term='developers'/><category term='XWT'/><category term='cursor'/><category term='ejb'/><category term='DSL'/><category term='ui design'/><category term='spring'/><category term='javaEE'/><category term='2010 World Cup'/><category term='world cup'/><category term='domain'/><category term='Mac OS X'/><category term='XText'/><category term='visibleWhen'/><category term='tdd'/><category term='performance'/><category term='DDD'/><category term='no more handles'/><category term='image'/><category term='training'/><category term='Handler'/><category term='South Africa'/><category term='jsf'/><category term='workshop'/><category term='soccer'/><category term='soap'/><category term='java'/><category term='NatTable'/><category term='authentication'/><category term='programming'/><category term='glimmer'/><category term='leak'/><category term='domain driven design'/><category term='property'/><category term='mockup'/><category term='jsp'/><category term='gdi'/><category term='command parameters'/><category term='communication'/><category term='java learning'/><category term='web services'/><category term='font'/><category term='OO'/><category term='richclientgui'/><category term='concurrency'/><category term='widgets'/><category term='java training'/><category term='creative'/><category term='java 6'/><category term='expressions'/><category term='RCP'/><category term='struts'/><category term='testers'/><category term='sleak'/><category term='gdi handles'/><category term='Table'/><category term='software'/><category term='servlets'/><category term='java training south africa'/><category term='abstraction'/><category term='color'/><category term='Eclipse'/><category term='worcester'/><category term='GUI development'/><category term='design'/><category term='regular expressions'/><category term='framework'/><category term='oo design'/><category term='java beginner'/><category term='java course south africa'/><category term='object-orientation'/><category term='SWT'/><title type='text'>Java, Mac, Software and other kaos</title><subtitle type='html'>The chronicles of a humble coder stumbling along on the adventurous road of developing software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-6100069626369696401</id><published>2011-01-27T23:22:00.000-08:00</published><updated>2011-01-27T23:27:38.258-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='domain model'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='object-orientation'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='oo design'/><category scheme='http://www.blogger.com/atom/ns#' term='oo analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='OO'/><category scheme='http://www.blogger.com/atom/ns#' term='GRAPS'/><category scheme='http://www.blogger.com/atom/ns#' term='use cases'/><title type='text'></title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande', LucidaGrande, Verdana, sans-serif; font-size: 13px; color: rgb(38, 38, 38); "&gt;I have finally launched a fantastic &lt;a href="http://www.jtraining.co.za/oo/oocourses.html#ooad"&gt;new workshop on Object-Oriented Analysis &amp;amp; Design&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I call this a workshop, since most of the time the participants are doing the work; in teams busy doing analysis and design, thus applying and internalizing the concepts and principles being taught. Some fundamental OO Analysis &amp;amp; Design skills, including introduction to various UML diagrams, are taught, and then applied on a project.&lt;br /&gt;&lt;br /&gt;This workshop starts from the first steps of requirements analysis (we talk about evolutionary requirements) to the Use Case model to the Domain Model to the Design Model, including principles and patterns such as GRASP, DDD (domain-driven design), TDD (test-driven development) and Design Patterns.&lt;br /&gt;&lt;br /&gt;Throughout the workshop we apply what we learn in an iterative manner to a single project that we need to analyse and design for.&lt;br /&gt;&lt;br /&gt;The few times I have already presented this workshop the participants and me had lots of fun while learning and applying very valuable OO analysis and design skills.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-6100069626369696401?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/6100069626369696401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=6100069626369696401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6100069626369696401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6100069626369696401'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2011/01/i-have-finally-launched-fantastic-new.html' title=''/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-5962973792403360336</id><published>2010-06-09T23:33:00.000-07:00</published><updated>2010-09-03T02:49:31.612-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XWT'/><category scheme='http://www.blogger.com/atom/ns#' term='XText'/><category scheme='http://www.blogger.com/atom/ns#' term='visual'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI development'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><category scheme='http://www.blogger.com/atom/ns#' term='gryphon'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='glimmer'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Making Java GUI Development easier</title><content type='html'>I’ve been programming in Java for about 13 years now, and I’ve becoming more and more convinced that there should be a much easier way to create GUI applications than writing Java code.&lt;br /&gt;&lt;br /&gt;This might sound like a strange statement, especially coming from a huge Java fan like me.&lt;br /&gt;&lt;br /&gt;I see teams struggle daily to build GUIs. Not because Swing or SWT/RCP is bad -these are two great UI frameworks- but just because such a lot of code must be written. The code is also not necessarily the most inspiring kind of code; there are only so many ways that you can write data-binding code using JFace data-binding, or do layouts doing GridLayout (try using FormLayout: much more fun).&lt;br /&gt;&lt;br /&gt;Good GUI applications are difficult to write (in my view much more difficult than your typical server-side code), but - and this is the thing to think about - about 80% of the code should “just happen”. (Some people might call this the scaffolding code or donkey code).&lt;br /&gt;&lt;br /&gt;Over the years I started searching for this elusive technology that will help me make this 80% of the GUI code “just happen”. I want to think about my domain, practice some good domain-driven development, and then blink my eyes and the GUI must be there. Then I can spend the rest of project doing the more difficult 20% of the code...&lt;br /&gt;&lt;br /&gt;What an adventure it is to search for this Holy Grail in the software world...&lt;br /&gt;&lt;br /&gt;One’s journey will perhaps start off with one of the most obvious first quests to go for (and in some development environments the only available quest...): &lt;strong&gt;the visual designer/builder/drag&amp;amp;dropping tool&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;A next quest might lead you to the highest peaks of &lt;strong&gt;UI DSL&lt;/strong&gt;s. Technologies like Glimmer, Gryphon, XScalaWT, ScalaSWT, XWT, etc.&lt;br /&gt;&lt;br /&gt;No adventure would be complete without a quest  into the dungeons of &lt;strong&gt;code generation tools&lt;/strong&gt;, like spring-roo, but for the Desktop GUI world. XText is an exciting project in this and the DSL realm that warrants some exploration.&lt;br /&gt;&lt;br /&gt;The deepest of the dungeons might reveal code generators that actually generate XML... perhaps a XML-based UI DSL, like XWT. But XML always begs the question: is it fit for human consumption? What if something does go wrong with the tooling, would you want to go and hack UI code in XML?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Back to the Basics...&lt;/strong&gt;&lt;br /&gt;In this adventure, as I went from quest to quest in search of that illusive  technology, I came to realise: probably the most important part of the GUI development process is a basic foundation of good practices and principles, to be applied no matter what technology you are using.&lt;br /&gt;&lt;br /&gt;And the first of these core principles: do not become bogged down with a particular GUI technology.&lt;br /&gt;&lt;br /&gt;Java offer a wide eco-system of technologies that play together very nicely. You do not even have to know Java to code great Java-based GUIs. Try out different approaches, different technologies. I know I’ve been playing very hard with various options, so I can avoid working hard writing donkey code.&lt;br /&gt;&lt;br /&gt;PS: I’m presenting a one-day workshop on this topic on the &lt;b&gt;8th of September&lt;/b&gt; in &lt;b&gt;Worcester&lt;/b&gt;, South Africa (near Cape Town). We’ll look at typical frustrations and issues with GUI development,  explore UI DSLs hands-on (yes, even straying away from Java in the process...), play with XText, talk about practices and principles, and generally have a lot of fun.&lt;br /&gt;&lt;a href="http://www.jtraining.co.za/ui/uicourses.html"&gt;More info here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-5962973792403360336?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/5962973792403360336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=5962973792403360336' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/5962973792403360336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/5962973792403360336'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/06/making-java-gui-development-easier.html' title='Making Java GUI Development easier'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-4562489344639372410</id><published>2010-05-27T04:36:00.000-07:00</published><updated>2010-05-27T05:05:40.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java beginner'/><category scheme='http://www.blogger.com/atom/ns#' term='java course south africa'/><category scheme='http://www.blogger.com/atom/ns#' term='world cup'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='java training'/><category scheme='http://www.blogger.com/atom/ns#' term='java training south africa'/><category scheme='http://www.blogger.com/atom/ns#' term='worcester'/><category scheme='http://www.blogger.com/atom/ns#' term='Cape Town'/><category scheme='http://www.blogger.com/atom/ns#' term='java learning'/><category scheme='http://www.blogger.com/atom/ns#' term='java courses'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='OO'/><category scheme='http://www.blogger.com/atom/ns#' term='South Africa'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Exciting new Java Courses in South Africa</title><content type='html'>I have been doing a lot of work around renewing my Java courses, talking to Heinz Kabutz in Crete, creating a new website.&lt;br /&gt;Why?&lt;br /&gt;Because I realized I have a passion for teaching others how to become great programmers. So am starting to concentrate more on training (while still doing enough real development work to keep the balance).&lt;br /&gt;&lt;br /&gt;I am very excited to announce three new open Java courses that are going to be presented in June/July in South Africa by me.&lt;br /&gt;&lt;br /&gt;First we have the &lt;a href="http://www.jtraining.co.za/java/javacourses.html#foundation"&gt;Java and OO Foundation course&lt;/a&gt;, from &lt;strong&gt;14-15 and 17-18 June 2010 &lt;/strong&gt;(16th is Youth Day), happening in Worcester, South Africa, at our new training facility there. I can recommend this course to anyone starting out with OO and Java. Most of the content comes from my friend Heinz Kabutz’s &lt;a href="http://www.javaspecialists.eu"&gt;JavaSpecialist&lt;/a&gt; Java Foundation course. &lt;br /&gt;&lt;br /&gt;Then we have our first presentation of the &lt;a href="http://www.jtraining.co.za/java/javacourses.html#intermediate"&gt;Java Intermediate Course&lt;/a&gt; happening from &lt;strong&gt;5 to 8 July&lt;/strong&gt;, also in Worcester. I can recommend this course to developers who are comfortable with the basics of the Java language and OO, and who wants to learn more about real life Java topics like using JUnit, concurrency, generics and annotations. &lt;br /&gt;&lt;br /&gt;Finally we have another big &lt;strong&gt;first for Africa&lt;/strong&gt;: the first presentation of the now famous &lt;a href="http://www.jtraining.co.za/java/javacourses.html#master"&gt;Java Specialist Master Course&lt;/a&gt;, from &lt;strong&gt;13 to 16 July 2010&lt;/strong&gt;. All those &lt;em&gt;Soccer World Cup &lt;/em&gt;fans out there: stay a week longer in South Africa and come attend this brilliant course, authored by Heinz Kabutz. &lt;br /&gt;&lt;br /&gt;I am extremely excited about our &lt;a href="http://www.jtraining.co.za/packages/packages/worcester.html"&gt;new training facilities&lt;/a&gt; in Worcester, which we call “The Loft @ PolymorphHQ”. Worcester is only about 100km away from Cape Town, a very scenic drive over the mountains. I am planning to combine all courses presented in Worcester with a bit of wine-tasting or even game-drive experiences. We are also investigating providing special packages that include accommodation. And we will definitely work in a nice steak and some good red wine with great Java discussions one of the evenings of the course.&lt;br /&gt;&lt;br /&gt;I also want to announce our The Loft opening special: if you &lt;a href="http://www.jtraining.co.za/packages/courses/register.html"&gt;register&lt;/a&gt; for both the Java and OO Foundation (14 June 2010) and the Java Intermediate (5 July 2010) courses, you save R7,000. &lt;br /&gt;&lt;br /&gt;I hope to have a lot of great Java developers coming out of Worcester these next few years :-)&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-4562489344639372410?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/4562489344639372410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=4562489344639372410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4562489344639372410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4562489344639372410'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/05/exciting-new-java-courses-in-south.html' title='Exciting new Java Courses in South Africa'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-4008052667560519817</id><published>2010-05-20T03:19:00.000-07:00</published><updated>2010-05-31T00:41:39.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gdi'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='sleak'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='color'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='no more handles'/><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='cursor'/><category scheme='http://www.blogger.com/atom/ns#' term='gdi handles'/><category scheme='http://www.blogger.com/atom/ns#' term='leak'/><title type='text'>No more handles: when the OS intrudes on cross-platformism</title><content type='html'>One of my clients recently contacted me in panic: "We get 'No more handles' exceptions in SWT. Help..."&lt;br /&gt;&lt;br /&gt;They have a quick big heavy-duty Eclipse RCP app running in their call centre, where a minute downtime can cause thousands of Rands (hmm, that would be thousands of Euros/Dollars as well) financial losses.&lt;br /&gt;&lt;br /&gt;Needless to say, this only happens on Windows. Windows limits the number of what they term "GDI handles". These are basically OS handles to graphical objects, like images, fonts, colours, cursors, and GC (as in Graphical Context, not garbage collection)&lt;br /&gt;For more background on this GDI handle problem, read &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://i-proving.ca/space/David+Jones/blog/2006-06-05_1"&gt;this article&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The important here is: in SWT you as developer MUST dispose all graphical objects yourself, just like working with e.g. file IO or database connections.&lt;br /&gt;&lt;br /&gt;In the normal way of working, you would e.g. create a RCP ViewPart, add widgets to it, and then eventually it is closed, and RCP dispose it and all the widgets on it. So for the typical widget, dialog or viewpart you are covered.&lt;br /&gt;&lt;br /&gt;However, when you start to instantiate your own Font, Color, Image, GC or Cursor, you need to keep track manually, and call dispose() on the instances.&lt;br /&gt;The best way is to make use of ImageRegistry, FontRegistry and ColorRegistry (look at JFaceResources class for the default registry instances).&lt;br /&gt;&lt;br /&gt;In real life, though, we have two big culprits:&lt;br /&gt;1) Developers like to create custom widgets (and yes, sometimes we actually need it as well). This typically entails using a number of these graphics classes, especially the GC class.&lt;br /&gt;&lt;strong&gt;A lot of developers then forget to call dispose() on the GC object after it has been used.&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;2) I find that a lot of people using Eclipse RCP or SWT does not know that they need to dispose these graphics objects, and they also do not use the registry classes. Or they might think they must only do it with Images, Colors and Fonts, and then they &lt;strong&gt;creating new Cursor and GC instances all over without disposing it&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;It takes only a few of these leaked instances to crash an application over time.&lt;br /&gt;&lt;br /&gt;How do I solve it?&lt;br /&gt;&lt;br /&gt;I have tried different tools, but found the best tool for me is &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://www.eclipse.org/swt/tools.php"&gt;Sleak&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Basically, you get the Sleak plugin, make it part of your runtime plugins, and then you need to change your perspectives to include the Sleak View as well.&lt;br /&gt;You can get a good tutorial on using it &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://eclipsesource.com/blogs/2009/04/17/finding-swt-leaks-with-sleak/"&gt;here&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Sleak can take a snapshot of the existing GDI handles that are open, with the option to give you a stacktrace so you can see where each one is created. Then you can open a screen, or perform some actions, and get a difference, which will indicate whether any new handles has been created form the previous snapshop.&lt;br /&gt;&lt;br /&gt;Now all you need is some patience, as you'll have to try out various functionality of your application, and find those handles that does not get disposed.&lt;br /&gt;&lt;br /&gt;I've sent some fixes to my client, and now only time will tell if I got all those leaks...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[Update 31-5-2010] I have found another tool that I want to play with that will help find these kind of leaks, as well as debug UI layouts: &lt;a href="http://sourceforge.net/apps/trac/yari/"&gt;Yari&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-4008052667560519817?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/4008052667560519817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=4008052667560519817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4008052667560519817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4008052667560519817'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/05/no-more-handles-when-os-intrudes-on.html' title='No more handles: when the OS intrudes on cross-platformism'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-71832588983714572</id><published>2010-05-12T14:41:00.000-07:00</published><updated>2010-05-12T14:53:52.279-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='courses'/><category scheme='http://www.blogger.com/atom/ns#' term='training'/><category scheme='http://www.blogger.com/atom/ns#' term='OO'/><category scheme='http://www.blogger.com/atom/ns#' term='South Africa'/><title type='text'>experts training experts</title><content type='html'>I am very honoured to have been certified by Dr Heinz Kabutz of &lt;a href="http://JavaSpecialists.EU"&gt;JavaSpecialists.EU&lt;/a&gt; to present his &lt;a href="http://www.javaspecialists.eu/courses/master.jsp"&gt;Java Specialist Master &lt;/a&gt;course. This is an excellent advanced Java™ course, the best by far (according to my totally objective point of view, and excuse the pun).&lt;br /&gt;&lt;br /&gt;We had a great time in Chania, Crete last week diving deep into the realm of Java.&lt;br /&gt;&lt;br /&gt;With a bit of planning we (as in my company &lt;a href="http://www.polymorph.co.za"&gt;Polymorph Systems&lt;/a&gt;) has launched our new &lt;a href="http://www.jtraining.co.za"&gt;Java and OO training website&lt;/a&gt; as well today, to coincide with us being able to advertise the Java Master course in Southern Africa now. Go read there now &lt;a href="http://www.jtraining.co.za/page2/page2.html"&gt;what this course is about&lt;/a&gt; and &lt;a href="http://www.jtraining.co.za/page2/page13/page13.html"&gt;why you should attend it&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I am extremely excited about presenting this new course, as well as some refactored introductory and intermediary courses on Java as well as Eclipse RCP and RAP. &lt;br /&gt;&lt;br /&gt;Too long has training companies in South Africa been getting away with mediocre courses presented by trainers with no real world experience. We are aiming to change that, starting today.&lt;br /&gt;&lt;br /&gt;For quality software, one needs quality training. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-71832588983714572?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/71832588983714572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=71832588983714572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/71832588983714572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/71832588983714572'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/05/experts-training-experts.html' title='experts training experts'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-7829164120291959522</id><published>2010-03-25T01:01:00.000-07:00</published><updated>2010-03-25T01:49:40.886-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='training'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='OO'/><title type='text'>Training by Coding</title><content type='html'>I have been presenting various Java, Eclipse and OO courses for a number of years now, and always tended to allow at least half of the courses’ time to be used doing practical exercises.&lt;br /&gt;&lt;br /&gt;This week is the first time I’m presenting a whole new Java learning experience: the students has to build a deliverable, running client-server application that persists to a database in one week’s time, using only Java SE. In this case the students only learned the Java basics the previous week.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;And they are enjoying it immensely. And I am enjoying it. This course really is a lot fun. &lt;br /&gt;&lt;/em&gt;&lt;br /&gt;It also makes me wonder: can’t I somehow combine this with the more theoretical introductory course? The difficulty would be to somehow cover the necessary theory on OO, Polymorphism and the various Java syntax and constructs, while allowing the students to spend at least 80% of the time coding an actual project, applying TDD, deploying deliverable code and learning some tricks and tips a theoretical course would not cover. I even throw in a bit of DDD.&lt;br /&gt;&lt;br /&gt;A week would probably not be enough, and then it gets more difficult selling the course to companies, as most companies can’t even spare one week in fear of their project plans being disturbed.&lt;br /&gt;&lt;br /&gt;I’m confident that this more practical and more interactive (as in extremely interactive) approach to introductory technical courses are the way forward, and this week proofs it for me. &lt;br /&gt;&lt;br /&gt;Keep an eye on this blog as I’ll be introducing changes into my existing &lt;a href="http://www.richclientgui.com/courses.php"&gt;Java, Eclipse RCP and OO courses&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;And, as always, I am very keen on hearing your thoughts around this. &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-7829164120291959522?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/7829164120291959522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=7829164120291959522' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7829164120291959522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7829164120291959522'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/03/training-by-coding.html' title='Training by Coding'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-1538892916473301316</id><published>2010-02-07T22:44:00.000-08:00</published><updated>2010-02-08T06:32:13.500-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Cape Town'/><category scheme='http://www.blogger.com/atom/ns#' term='developers'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='South Africa'/><title type='text'>South Africa Eclipse Expert Group</title><content type='html'>&lt;div&gt;&lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; technologies are not that widely used in South Africa (except for the Eclipse IDE). As a result, there are not many (if any) companies concentrating on building skills in that area. However, an increasing number of local companies are using especially&lt;a href="http://www.eclipse.org/rcp"&gt; Eclipse RCP&lt;/a&gt; to build rich applications with, or introducing &lt;a href="http://www.osgi.org/About/Technology"&gt;OSGi&lt;/a&gt; in their architecture (and to code Eclipse properly, one needs to know OSGi).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Vision&lt;/b&gt;&lt;/div&gt;&lt;div&gt;My &lt;a href="http://www.richclientgui.com/"&gt;company&lt;/a&gt; recently had the vision to create &lt;i&gt;THE&lt;/i&gt; leading Eclipse technologies expert group in Southern Africa. We have been spending more and more time supporting other companies in their use of Eclipse technologies, as well as increasing our portfolio of Eclipse-based projects. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And we're running out of skilled people.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We now started to grow a team of Java developers to become a team of experts on Eclipse technologies, including RCP, RAP, GEF, EclipseLink and OSGi.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Mission&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Our mission for the Eclipse Expert Group can be stated as:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;become experts in Eclipse technologies&lt;/li&gt;&lt;li&gt;deliver quality software using Eclipse technologies &lt;/li&gt;&lt;li&gt;provide expert advise and support to other companies that need it&lt;/li&gt;&lt;li&gt;increase the local Eclipse skills by providing training and mentoring&lt;/li&gt;&lt;li&gt;contribute to the Eclipse community by participating in open-source projects&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For me this is a very exciting vision. &lt;/div&gt;&lt;div&gt;To the wider Eclipse community out there (of whom very few are based in South Africa) : I want to invite you to provide me with tips, input and advise on growing this team; maybe even come and visit us as part of your next Africa safari, or supply opportunities to do work for you. One never knows, maybe in a few years we'll have some international Eclipse conferences down here :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PS: We started on the open-source road by making the commercial version of &lt;a href="http://launchpad.net/rcptoolbox"&gt;RCP Toolbox&lt;/a&gt; open-source.&lt;/div&gt;&lt;div&gt;&lt;br /&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/1872922649370966015-1538892916473301316?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/1538892916473301316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=1538892916473301316' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/1538892916473301316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/1538892916473301316'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/02/south-africa-eclipse-expert-group.html' title='South Africa Eclipse Expert Group'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-2585573672122551069</id><published>2010-01-19T02:39:00.000-08:00</published><updated>2010-01-21T00:34:06.729-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='domain'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='ui design'/><category scheme='http://www.blogger.com/atom/ns#' term='domain driven design'/><category scheme='http://www.blogger.com/atom/ns#' term='mockup'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='communication'/><title type='text'>Domain-driven UI design</title><content type='html'>We have all read and are actively using some sound &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;DDD&lt;/a&gt; principles (I hope :-) ).&lt;br /&gt;&lt;br /&gt;For some clients I found the approach of discussing the domain model using an ubiquitous language and various diagrams and (perhaps) written documentation just does not work very well. We can have days of workshops with the domain experts, and still, when presenting some iteration of work, the questions and confusion come pouring in.&lt;br /&gt;But that is part of DDD, getting feedback, refining the language and the model, etc.&lt;br /&gt;&lt;br /&gt;Now step back a moment, and look a bit differently at solving this communication gap.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;We can use UI mockups and prototypes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;There is always the danger of going into too much irrelevant detail too soon, or being side-tracked into application infrastructure, or more work involved in presenting a domain concept on a UI mockup or prototype than with a diagram and descriptive paragraph of text.&lt;br /&gt;&lt;br /&gt;However, once again DDD comes to save the day, from there what I call "Domain-driven UI design". What do I mean with this?&lt;br /&gt;&lt;br /&gt;We use DDD to design the model, but we use UI mockups, perhaps prototypes as well, as a way of presenting the model we are building to the domain experts, in stead of diagrams or other forms of presenting the model.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;These UI mockups still need to strictly adhere to the domain language!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In a project I'm busy with currently, we base all the workshops we have with the domain experts around the UI screens, while still coming back to discussing the domain objects and model while busy with screens depicting those objects.&lt;br /&gt;We still use an &lt;/span&gt;ubiquitous&lt;span&gt; language, we still build up a rich domain model, but we use primarily UI designs to present it to the domain experts, because for this specific group of experts that is what they understand best. It is more concrete for them, thus allowing them to give better feedback.&lt;br /&gt;&lt;br /&gt;However, it does place a big responsibility on the facilator: he/she must be able to keep the domain discussion from being side-tracked by non-domain concerns that are typically also part of a UI mockup or prototype. At such workshops we do not want to discuss the exact border width to use for checkboxes... (there is a place for such discussions, but not when using the UI as a way to facilitate domain design discussions)&lt;br /&gt;&lt;br /&gt;And behind the scenes?&lt;br /&gt;&lt;br /&gt;When we go back to our development work, we first update our domain model (wherever that is depicted), then our tests, then our domain objects, and lastly the next round of UI prototype screens and/or mockups. We find that taking the domain model through to the UI level actually help enrich our understanding of it, and ultimately enrich the communication process with the clients, leading to more valuable feedback.&lt;br /&gt;&lt;br /&gt;Ultimately good design and good code is mostly about good communication, and using this domain-driven UI design approach has greatly enhanced the communication in a number of projects I've been involved with.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;:&lt;br /&gt;I can really recommend Erik Evan's book on DDD:&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0321125215?ie=UTF8&amp;amp;tag=hermlintblog-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0321125215"&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=hermlintblog-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321125215" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-2585573672122551069?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/2585573672122551069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=2585573672122551069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2585573672122551069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2585573672122551069'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2010/01/domain-driven-ui-design.html' title='Domain-driven UI design'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-2415637300991350719</id><published>2009-10-06T04:22:00.000-07:00</published><updated>2009-10-06T04:25:51.529-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='commandParameter'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='Actions'/><category scheme='http://www.blogger.com/atom/ns#' term='command parameters'/><title type='text'>Eclipse Tips: Commands</title><content type='html'>I recently discovered a nice &lt;a href="http://blog.eclipse-tips.com/"&gt;blog&lt;/a&gt; by G.R. Prakash that has a number of posts about the Eclipse Commands API. &lt;br /&gt;&lt;br /&gt;Please do yourself the favour and visit the posts below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/01/commands-part-1-actions-vs-commands.html"&gt;Eclipse Tips: Commands Part 1: Actions vs Commands&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/01/commands-part-2-selection-and.html"&gt;Eclipse Tips: Commands Part 2: Selection and Enablement of IHandlers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2008/12/commands-part-3-parameters-for-commands.html"&gt;Eclipse Tips: Commands Part 3: Parameters for Commands&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/01/commands-part-4-misc-items.html"&gt;Eclipse Tips: Commands Part 4: Misc Items&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/02/commands-part-5-authentication-in-rcp.html"&gt;Eclipse Tips: Commands Part 5: Authentication in RCP Applications&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/03/commands-part-6-toggle-radio-menu.html"&gt;Eclipse Tips: Commands Part 6: Toggle and Radio menu contributions&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eclipse-tips.com/2009/05/commands-part-7-adding-standard.html"&gt;Eclipse Tips: Commands Part 7: Adding standard commands&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I will also be adding some more posts on Eclipse Commands shortly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-2415637300991350719?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/2415637300991350719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=2415637300991350719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2415637300991350719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2415637300991350719'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/10/eclipse-tips-commands.html' title='Eclipse Tips: Commands'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-1281602677347211893</id><published>2009-08-20T02:05:00.000-07:00</published><updated>2009-08-31T13:55:48.752-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='creative'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='developers'/><category scheme='http://www.blogger.com/atom/ns#' term='ui design'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Myths of UI Design</title><content type='html'>&lt;b&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;I recently presented a workshop on UI design in the software development world,  and as part of the workshop we talked briefly about some common UI Design myths.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;I thought it might be useful to iterate some of the myths again on my blog. (You can find the slides of my workshop presentation &lt;a href="http://www.spin.org.za/cms/sites/default/files/CT-SPIN49-HermanLintvelt-ArtConstraints.pdf"&gt;here&lt;/a&gt;). This is from my experience in designing and implementing user interface applications, as a software developer, not a user experience engineer or human-computer-interface expert.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;Myth #1: Developers know what users want&lt;/b&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;One of my favourite comics from &lt;a href="http://www.ok-cancel.com/"&gt;www.ok-cancel.com&lt;/a&gt; is this one:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;img src="http://www.ok-cancel.com/strips/okcancel20031010.gif" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Need I say more?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;I can also heavily paraphrase &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt; (from his book "&lt;a href="http://www.amazon.com/gp/product/1893115941?ie=UTF8&amp;amp;tag=hermlintblog-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1893115941"&gt;User Interface Design for Programmers&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=hermlintblog-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1893115941" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;") and say that we forget that:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;most users cannot read&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;most users cannot use a mouse&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;I'm not trying to ridicule the end-user here. (I'm a end-user myself.) Joel explains the much better than me, so grab hold of his book. But what it boils down to is that we need to keep the interface as simple as possible. Users will typically not read long sentences, or even phrases, in a dialog or wizard, or wherever else you display them. A lot of users will also not even read the user manual (I never do...). &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;We developers are also inclined to think all users have super-duper mouse skills, honed on numerous Dota or Quake3 games, using great laser-mouses on clean desks. We forget that some computers are used in greasy factories or workshops, a lot of cheap inaccurate mouses are being sold daily and everyone does not have nifty 24" or bigger monitors.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Somehow the simplicity thing is very difficult to grasp... &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Look at the numerous overly complex, distractingly busy websites out there. Look at all the feature-bloated, monstrous applications we have to struggle with. Because we as developers like to tune our operating systems and play with every setting we can find, does not mean our end-users wants all that choice and features. For them the software is just a tool to get their real work done, hopefully in as simple as possible way.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;This does not mean we must make all our software so simple that it does not add value to the user. Some UIs needs to be complex to provide what the user needs, e.g. IDEs. However, these the user will get to know over time, and get to expect how it will behave. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;I think the challenge is to find the simplest possible design that provides what the user expects.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Myth #2: UI Design is art, just do what you want&lt;br /&gt;&lt;/b&gt;&lt;div&gt;&lt;div&gt;“Art is about freedom, Design is about constraints” is a quote that I read a while ago on a website, but I could not find the quote again. (If whoever wrote this somehow reads this post, please contact me and introduce yourself :-) ).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;UI design and implementation is a very creative process for me, however, it is a process that must take a lot of constraints into consideration. One might naively think that you can let your creative side just take over and be totally free with your designs. Unfortunately you will most probably loose all your users along the way; scared away by the radically new ideas and metaphors that you so artfully brought into the software.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Life is at its core a balancing act; the same with UI design. You need to be creative, but you also need to be consistent with what the user expects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course there are always some other less welcome constraints that typically influence a project. You know... lack of money, tyrannical management, looming deadlines, issues with the GUI framework that was chosen, and so forth. These all join together to kill of that spark of creativity... (or sometimes actually ignite it, like a wild animal trapped in a corner). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Myth #3: UI can be left for last&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The sad truth in the software development arena is that UI design and implementation somehow gets left for the last minute in many projects out there. &lt;/div&gt;&lt;div&gt;The feeling I get from a lot of companies where I consult or do development is that the user interface part of a project is seen as being inferior to “Server development”. You get The System, where all the experienced developers are being used, and then there is that "little bit off to one side" where some junior code monkeys get dumped to spin out some quick check-boxes.&lt;/div&gt;&lt;div&gt;[Disclaimer: I do not see these guys as junior code monkeys; that is part of the feelings floating around that I observed.]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I see this, I want to scream (in some cases I do scream): People, ARE YOU MAD! The user interface is the end-users' view of the system. It MUST be professional and conform to there (highly complex, yet simple) expectations, otherwise the whole system will be perceived as a failure. It does not matter if your database can handle 10000 transactions in a second for 100000 users connected simultaneously and compress the data such that each record takes up only 1 bit. If the user interface(s) of the system is lacking, your whole project will be a failure. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I put it very bluntly (you might say provocatively) at the UI workshop the other night: server-side coding is very easy. You design some domain objects and some business logic, and select the framework that ties everything together. There is known input and known logic to get some known output from that. &lt;/div&gt;&lt;div&gt;On the other hand, UI development is extremely difficult. You have two major unknowns:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;the user (show me a predictable user)&lt;/li&gt;&lt;li&gt;the windowing system of the OS (Remember: the experienced guys has worked on the kernels, while the UI framework and windowing systems of the different OS's has been build by the new kids on the block...)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;What does this mean? Put your good developers on GUI development as well. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, before you get too worked up, I have stated it in the extreme above. However, it seems that there is a mental block about this at a lot of companies. Not all companies, no. But a lot. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A lot of successful companies have banished this "server team" vs. "gui team" approach, and actually get their developers to work on all the layers that make up the systems. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm going to wrap up this post now, and hope for the same kind of debate I got at the workshop... &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&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/1872922649370966015-1281602677347211893?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/1281602677347211893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=1281602677347211893' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/1281602677347211893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/1281602677347211893'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/08/myths-of-ui-design.html' title='Myths of UI Design'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-9149686743969012476</id><published>2009-08-11T13:29:00.000-07:00</published><updated>2009-08-11T13:30:22.262-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cape Town'/><category scheme='http://www.blogger.com/atom/ns#' term='ui design'/><category scheme='http://www.blogger.com/atom/ns#' term='spin'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='workshop'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>CT-SPIN #49: UI Design Workshop</title><content type='html'>&lt;div&gt;On 19 August I am going to present what I hope is going to be a fun-filled and enlightening evening workshop on pragmatic UI Design at the Cape Town SPIN group. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We are going to look at UI Design in a hands-on way. So if you are in Cape Town region then, come and pop in:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For more detail, visit this link:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.spin.org.za/cms/node/18"&gt;CT-SPIN #49: "Art is about freedom, Design is about &lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.spin.org.za/cms/node/18"&gt;constraints" | Cape Town SPIN&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-9149686743969012476?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/9149686743969012476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=9149686743969012476' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/9149686743969012476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/9149686743969012476'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/08/ct-spin-49-ui-design-workshop.html' title='CT-SPIN #49: UI Design Workshop'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-2543282458664282978</id><published>2009-08-11T03:36:00.000-07:00</published><updated>2009-08-11T03:37:38.165-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='regular expressions'/><title type='text'>8 Regular Expressions You Should Know - Nettuts</title><content type='html'>&lt;div&gt;I recently had to do some regular expression matching against email addresses. This link is really handy:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/"&gt;8 Regular Expressions You Should Know - Nettuts&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-2543282458664282978?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/2543282458664282978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=2543282458664282978' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2543282458664282978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2543282458664282978'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/08/8-regular-expressions-you-should-know.html' title='8 Regular Expressions You Should Know - Nettuts'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-6728014682726594968</id><published>2009-08-11T02:45:00.000-07:00</published><updated>2009-08-11T03:29:39.030-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='domain'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='abstraction'/><title type='text'>The bad side of good abstraction</title><content type='html'>Good, well-designed abstraction can be bad. Or rather, has some negative aspects as well.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me explain.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In most projects I have been involved in some form of abstraction layer was build on top of the libraries and frameworks used. A kind of domain-specific framework. &lt;/div&gt;&lt;div&gt;Typically this layer is meant to make it easier to build the system. The (more experienced/senior) developer(s) would implement this, thereby allowing the rest to work with a limited facade of the lower level libraries. I have also instigated and added to such layers many times; it is especially useful to build a more domain oriented application framework on top of the general Eclipse RCP framework (or Swing, in the earlier days). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If this layer is designed and implemented well, it usually enhances productivity and generally makes everyone feel all happy and content.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After a discussion the other day with a very bright developer, who is still new to Eclipse RCP, I came to realise there is one serious bad issue with this approach: skills development.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This guy has been working on a very complex RCP application, using a lot of the abstracted custom framework and some of the "low level" RCP itself. And then came the day he had to develop an Eclipse RCP app from scratch, in another business domain, without the help of the abstraction layer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suddenly he had to start learning a lot of "new" RCP concepts and API. Things that has been hidden (read: encapsulated) away from him until now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This led me to start thinking about my approach when I mentor or lead teams: I must somehow maintain a balance between this kind of (necessary) abstraction that enhanced productivity, and still allowing the team members to pick up the necessary skills on the "hidden" areas.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Please feel free to contribute your ideas and possible solutions to this balancing game as comments. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-6728014682726594968?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/6728014682726594968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=6728014682726594968' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6728014682726594968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6728014682726594968'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/08/bad-side-of-good-abstraction.html' title='The bad side of good abstraction'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-9016916477291040374</id><published>2009-07-14T08:10:00.000-07:00</published><updated>2009-07-14T08:19:22.879-07:00</updated><title type='text'>One-armed but still typing</title><content type='html'>I'm sitting here and typing as fast as I can with one hand.&lt;br /&gt;&lt;br /&gt;In my other arm I am holding my newly born baby daughter, now one week old. She has kept us quite busy these last 2 weeks, so my blogs has dried up a bit.&lt;br /&gt;&lt;br /&gt;Just some of the things I've been meaning to blog about, and will hopefully find time for soon:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Some exciting happenings on the Java and OO training front in South Africa.&lt;/li&gt;&lt;li&gt;An Eclipse Democamp/ informal conference in Cape Town, RSA&lt;/li&gt;&lt;li&gt;An informal Java conference (or maybe combine with 2), also in Cape Town&lt;/li&gt;&lt;li&gt;A quick glance at Eclipse Pulsar and MJT for developing Java ME midlets&lt;/li&gt;&lt;li&gt;How to integrate J2me-Polish with your Eclipse midlet projects&lt;/li&gt;&lt;li&gt;Further blogs about the Eclipse Commands API&lt;/li&gt;&lt;li&gt;Using AspectJ to get rid of all kinds of listeners and donkey code when implementing GUIs in Java.&lt;/li&gt;&lt;li&gt;and so much more...&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;But currently I must balance between staring at my daughter, and doing some paying work :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just keep an eye on this space, though.&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/1872922649370966015-9016916477291040374?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/9016916477291040374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=9016916477291040374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/9016916477291040374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/9016916477291040374'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/07/one-armed-but-still-typing.html' title='One-armed but still typing'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-7893639568045751736</id><published>2009-06-18T23:21:00.001-07:00</published><updated>2009-06-18T23:47:22.220-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='2010 World Cup'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='soccer'/><category scheme='http://www.blogger.com/atom/ns#' term='South Africa'/><title type='text'>Java Developer Conference in South Africa</title><content type='html'>&lt;p&gt;One thing that I miss a great deal in South Africa is a choice of good Java developer conferences, demo camps, etc. Okay, drop 'good' and replace it with 'any'.&lt;br /&gt;&lt;br /&gt;About once every 3 years Sun hosts the Java Dev Days in Johannesburg, and that is about it.&lt;br /&gt;&lt;br /&gt;I started thinking it is time to start creating interest in a Eclipse and/or Java conference just before or after the 2010 Soccer World cup here in SA. To boost the numbers of SA developers with the visiting fundis from overseas.  &lt;br /&gt;&lt;br /&gt;It seems both the &lt;a href="http://www.eclipse.org/membership/"&gt;Eclipse Foundation&lt;/a&gt; and &lt;a href="http://www.eclipse-training.net/about_us"&gt;Eclipse Training Alliance&lt;/a&gt; would be keen to support an Eclipse focused event. I'm starting to determine the feasibility of an Eclipse-only event in SA. &lt;br /&gt;&lt;br /&gt;A great option for the smallish size of the SA developer community would be to combine Eclipse and other Sun-side Java technologies, but would possible politics between the Sun and Eclipse organisations allow this?&lt;br /&gt;&lt;br /&gt;It would be great if you can indicate in a comment or tweet me &lt;a href="http://twitter.com/hermanlintvelt"&gt;@hermanlintvelt&lt;/a&gt; about your interest in such an event, whether you are interested in Eclipse technologies or not and if you are from South Africa or not. &lt;br /&gt;&lt;br /&gt;Would be great to hear from you, Herman.   &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Posted with &lt;a href='http://lifecast.sleepydog.net'&gt;LifeCast&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/1872922649370966015-7893639568045751736?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/7893639568045751736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=7893639568045751736' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7893639568045751736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7893639568045751736'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/06/developer-conference-in-south-africa.html' title='Java Developer Conference in South Africa'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-4256722311152948898</id><published>2009-06-03T08:17:00.000-07:00</published><updated>2009-06-03T08:22:23.569-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testers'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='visibleWhen'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='expressions'/><title type='text'>Eclipse RCP Commands Part 3: visibleWhen and Core Expressions</title><content type='html'>This is the third part of my blog series on the Eclipse Commands framework. Please see &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-one.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands API Part One"&gt;Part One&lt;/a&gt; for an outline of topics covered in the various blogs.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Limiting visibility of Commands&lt;/h2&gt;&lt;br /&gt;A powerful feature of the Commands framework is that you can declare in the &lt;em&gt;plugin.xml&lt;/em&gt; when a Command should be visible (or rather when specific menu contributions should be visible) and when it should be enabled. This is done by using what is called &lt;a href="http://wiki.eclipse.org/Command_Core_Expressions" title="Command Core Expressions - Eclipsepedia"&gt;core expressions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a name="simple"&gt;&lt;/a&gt;&lt;h3&gt;Simple &lt;em&gt;visibleWhen&lt;/em&gt; definition&lt;/h3&gt;&lt;br /&gt;Let us take a simple example first: we want to limit the &lt;em&gt;Annotate eBook&lt;/em&gt; command (from the example in &lt;a href="http://hermanlintvelt.blogspot.com/2009/06/eclipse-rcp-commands-api-review-of-part.html"&gt;Part Two: Quick Review&lt;/a&gt;) to only show in the context menu if one item is selected in the view. If no item is selected, or more than one, it must not appear in the menu.&lt;br /&gt;&lt;li&gt;First select the &lt;strong&gt;popup:org.eclipse.ui.popup.any?after=additions&lt;/strong&gt; menu contribution extension element&lt;br /&gt;&lt;li&gt;Now select the &lt;em&gt;Annotate&lt;/em&gt; command element, right-click and choose &lt;strong&gt;New -&amp;gt; visibleWhen&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;checkEnabled&lt;/strong&gt; value to &lt;em&gt;false&lt;/em&gt; (setting to &lt;em&gt;true&lt;/em&gt; will use the enabled state of the command to determine the visibility)&lt;br /&gt;&lt;li&gt;Right-click on the &lt;strong&gt;visibleWhen&lt;/strong&gt; element, and choose &lt;strong&gt;New -&amp;gt; with&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;variable&lt;/strong&gt; attribute to "&lt;em&gt;activeMenuSelection&lt;/em&gt;". "&lt;em&gt;activeMenuSelection&lt;/em&gt;" is a known expressions variable that will get resolved when the platform must populate the context menu. Se &lt;a href="#vars"&gt;the list&lt;/a&gt; of other known expression variables.&lt;br /&gt;&lt;li&gt;Right-click on the &lt;strong&gt;activeMenuSelection(with)&lt;/strong&gt; element and choose &lt;strong&gt;New -&amp;gt; count&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;value&lt;/strong&gt; attribute for &lt;em&gt;count&lt;/em&gt; to "&lt;strong&gt;1&lt;/strong&gt;". &lt;br /&gt;&lt;p&gt;&lt;br /&gt;We have now set up the context-menu contribution to only show the &lt;em&gt;Annotate&lt;/em&gt; command when one and only one item in the view is selected. That was not so difficult, was it? I remember spending hours on creating nice selection behaviour helper classes for IActionDelegate-based frameworks, and still not getting the initial visibility or enabling of the actions in the menus right, due to constraints with that approach.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a name="simpleexample"&gt;&lt;/a&gt;The menu contributions extension in the &lt;em&gt;plugin.xml&lt;/em&gt; now looks like:&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.menus&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;menu:file?before=quit&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;O&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;A&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;popup:org.eclipse.ui.popup.any?after=additions&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;label=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Annotate&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;A&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;visibleWhen&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;checkEnabled=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;false&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;with&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;variable=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;activeMenuSelection&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;count&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;value=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;1&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/count&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/with&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/visibleWhen&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="expressiondef"&gt;&lt;/a&gt;&lt;h3&gt;Expression Definitions&lt;/h3&gt;&lt;br /&gt;Before I delve more deeply into even more interesting &lt;em&gt;visibleWhen&lt;/em&gt; capabilities, first a very nifty tip on core expressions: it is possible to declare a specific expression definition, and then just refer to that definition from your &lt;em&gt;visibleWhen, activeWhen&lt;/em&gt;, etc elements. &lt;br /&gt;&lt;br /&gt;We do this with the &lt;strong&gt;org.eclipse.core.expressions.definitions&lt;/strong&gt; extension. To define an expression that checks that only one item is selected:&lt;br /&gt;&lt;li&gt;Add the &lt;strong&gt;org.eclipse.core.expressions.definitions&lt;/strong&gt; extension (click &lt;strong&gt;Add...&lt;/strong&gt; on Extensions tab of plugin manifest editor, you might need to uncheck the "&lt;em&gt;Show only extension points from the required plug-ins&lt;/em&gt;" checkbox)&lt;br /&gt;&lt;li&gt;Give a proper &lt;strong&gt;id&lt;/strong&gt; to your definition, e.g. &lt;em&gt;expression.onlyOneItemSelected&lt;/em&gt;&lt;br /&gt;&lt;li&gt;Right-click on the &lt;em&gt;expression.onlyOneItemSelected&lt;/em&gt; element and choose &lt;strong&gt;New -&amp;gt; with&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;variable&lt;/strong&gt; attribute to "&lt;em&gt;activeMenuSelection&lt;/em&gt;".&lt;br /&gt;&lt;li&gt;Right-click on the &lt;strong&gt;activeMenuSelection(with)&lt;/strong&gt; element and choose &lt;strong&gt;New -&amp;gt; count&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;value&lt;/strong&gt; attribute for &lt;em&gt;count&lt;/em&gt; to "&lt;strong&gt;1&lt;/strong&gt;". &lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;You might have noticed it is the same steps as those followed for a &lt;a href="#simple"&gt;simple visibleWhen definition&lt;/a&gt; above.&lt;br /&gt;For those who rather do it directly in the&lt;em&gt; plugin.xml&lt;/em&gt;, here is the &lt;strong&gt;org.eclipse.core.expressions.definitions&lt;/strong&gt; extension declaration:&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.core.expressions.definitions&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;definition&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;expression.onlyOneItemSelected&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;with&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;variable=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;activeMenuSelection&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;count&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;value=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;1&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/count&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/with&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/definition&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;How do I use the expression definition?&lt;/h4&gt;&lt;br /&gt;What do you gain with first defining an expression? Well, you can reuse this definition in multiple places in your &lt;em&gt;plugin.xml&lt;/em&gt; if you need the same expression, whether it is for a&lt;em&gt; visibleWhen, activeWhen &lt;/em&gt;or &lt;em&gt;enabledWhen&lt;/em&gt; declaration.&lt;br /&gt;&lt;br /&gt;To replace our expression for our context menu contribution with the definition, you simply do the following:&lt;br /&gt;&lt;li&gt;Select the &lt;em&gt;activeMenuSelection(when)&lt;/em&gt; element under the &lt;em&gt;popup:org.eclipse.ui.popup.any?after=additions&lt;/em&gt; menu contribution's &lt;em&gt;visibleWhen&lt;/em&gt; element, right-click and select &lt;strong&gt;Delete&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Right-click again on the &lt;em&gt;visibleWhen&lt;/em&gt; element and choose &lt;strong&gt;New -&amp;gt; reference&lt;/strong&gt;&lt;br /&gt;&lt;li&gt;Set the &lt;strong&gt;definitionId&lt;/strong&gt; attribute to &lt;em&gt;expression.onlyOneItemSelected&lt;/em&gt; (i.e. the &lt;strong&gt;id&lt;/strong&gt; of the expression definition you want to use to evaluate whether the menu contribution must be visible or not)&lt;br /&gt;&lt;p&gt;&lt;br /&gt;If you run the application now, it should still behave the same as before we used our own definition, but now we are ready for a much more complex playing field. Underneath is a screenshot of how the extension declarations should look in the Plugin Editor.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://blog.richclientgui.com/wp-content/uploads/2009/06/extensions-commands-4.png" alt="Extensions Commands 4" height="311" width="479"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="expressions"&gt;&lt;/a&gt;&lt;h2&gt;To infinity and beyond: the power of expressions&lt;/h2&gt;&lt;br /&gt;We have seen a very basic expression up to now. You should have seen a number of other possible items to choose from when you selected &lt;strong&gt;New -&amp;gt; with&lt;/strong&gt; in the steps above. I list them below. These can all be used to build up complex expressions that gets evaluated at runtime to determine whether a specific menu contribution should be visible or not, if used in conjunction with a visibleWhen element.&lt;br /&gt;&lt;img src="http://blog.richclientgui.com/wp-content/uploads/2009/06/possible-expression-elements.png" alt="Possible Expression Elements" height="307" width="452"&gt;&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;th&gt;Element&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;adapt&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to adapt the object in focus (i.e. the object passed to the expression) to the specified &lt;strong&gt;type&lt;/strong&gt;. See &lt;a href="#adapt"&gt;Using adapt&lt;/a&gt; for more information.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;and&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;AND the results from evaluating the sub-elements&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;count&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to count the number of elements in a collection. The &lt;strong&gt;value&lt;/strong&gt; attribute be an integer or a supported wildcard. See &lt;a href="#count"&gt;Using count&lt;/a&gt; for more information.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;equals&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to check equality of the focussed object with the specified &lt;strong&gt;value&lt;/strong&gt; attribute&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;instanceof&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to perform an instanceof check on the object in focus. See &lt;a href="#instanceof"&gt;Using instanceof&lt;/a&gt; for more information.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;iterate&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to iterate over a collection, if the focussed object is of type &lt;em&gt;java.util.Collection&lt;/em&gt;. See &lt;a href="#iterate"&gt;Using iterate&lt;/a&gt; for more information.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;NOT the results from evaluating the sub-elements&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;or&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;OR the results from evaluating the sub-elements&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;reference&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;This is the element we use to refer to an expression defined under &lt;strong&gt;org.eclipse.core.expressions.definitions&lt;/strong&gt;. The &lt;strong&gt;definitionId&lt;/strong&gt; is the unique id of the expression definition to use for the evaluation.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;systemTest&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to test a system property, where &lt;strong&gt;property&lt;/strong&gt; is the name of the property to get via System.getProperty, and &lt;strong&gt;value&lt;/strong&gt; is the expected value to test against (as &lt;em&gt;String&lt;/em&gt; value).&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;test&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use this element to test the &lt;strong&gt;value&lt;/strong&gt; of a specific &lt;strong&gt;property&lt;/strong&gt; on the focussed object. See &lt;a href="#test"&gt;Using test&lt;/a&gt; for more information.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;with&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Use to change the object to inspect or focus on to the object referenced by the &lt;strong&gt;variable&lt;/strong&gt; attribute. See &lt;a href="#vars"&gt;the list of available expression variables&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;resolve&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Resolve does almost the same as &lt;strong&gt;with&lt;/strong&gt;, but it allows the use of a custom &lt;em&gt;IVariableResolver&lt;/em&gt;, and passing the specified &lt;strong&gt;args&lt;/strong&gt; as arguments to the variable resolver. More detail might be topic of a future blog post. I must admit, I have never used this one.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;h4&gt;Note on String values&lt;/h4&gt;&lt;br /&gt;The &lt;strong&gt;value&lt;/strong&gt; attribute for the above elements gets specified as some string. Here follows the extract from the Eclipse online help on how that String value might get converted:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;em&gt;When specifying a value to be tested against any of these expressions, the value is assumed to be a string except for when the following conversions are successful:&lt;br /&gt;&lt;li&gt;the string "true" is converted into Boolean.TRUE&lt;br /&gt;&lt;li&gt;the string "false" is converted into Boolean.FALSE&lt;br /&gt;&lt;li&gt;if the string contains a dot, the interpreter tries to convert the value into a Float object&lt;br /&gt;&lt;li&gt;if the string only consists of numbers, the interpreter converts the value into an Integer object&lt;br /&gt;the conversion into a Boolean, Float, or Integer can be suppressed by surrounding the string with single quotes.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="adapt"&gt;&lt;/a&gt;&lt;h4&gt;Using adapt&lt;/h4&gt;&lt;br /&gt;&lt;strong&gt;Adapt&lt;/strong&gt; is used to adapt the object in focus (you can see this as the object provided or specified by the parent element) to the type specified its the &lt;strong&gt;type&lt;/strong&gt; attribute. Any sub-elements of the adapt element will be evaluated against the adapted object. Read up about &lt;em&gt;IAdapterFactory&lt;/em&gt; and &lt;em&gt;IAdaptable&lt;/em&gt; interfaces for more information about adaption.&lt;br /&gt;If the object can be adapted, the adapt evaluate to &lt;strong&gt;true&lt;/strong&gt;. E.g. we can define an expression for evaluating if something adapts to the &lt;em&gt;ICountable&lt;/em&gt; interface.&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.core.expressions.definitions&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;definition&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;isCountable&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;adapt&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;type=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.core.expressions.ICountable&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/adapt&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/definition&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="instanceof"&gt;&lt;/a&gt;&lt;h4&gt;Using instanceof&lt;/h4&gt;&lt;br /&gt;This is used to perform an instanceof check on the object in focus. We can for example enhance our &lt;em&gt;Annotate eBook&lt;/em&gt; menu contribution in the &lt;em&gt;File&lt;/em&gt; menu to only display if at least on of the selected items is an instance of &lt;em&gt;java.lang.String&lt;/em&gt; (iterate gets discussed &lt;a href="#iterate"&gt;here&lt;/a&gt;):&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.menus&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;menu:file?before=quit&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;O&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;A&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;visibleWhen&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;checkEnabled=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;false&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;with&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;variable=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;selection&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;iterate&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;ifEmpty=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;false&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;operator=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;or&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;instanceof&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;value=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;java.lang.String&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;instanceof&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/iterate&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/with&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/visibleWhen&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="iterate"&gt;&lt;/a&gt;&lt;h4&gt;Using iterate&lt;/h4&gt;&lt;br /&gt;Iterate can be used if the object in focus is a &lt;em&gt;java.util.Collection&lt;/em&gt; (e.g. when &lt;strong&gt;with&lt;/strong&gt; is used in the parent element and the &lt;strong&gt;variable&lt;/strong&gt; attribute is set to "&lt;em&gt;selection&lt;/em&gt;"). It iterates through the collection, and evaluate the sub-elements against each item in the collection. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;The &lt;strong&gt;operator&lt;/strong&gt; attribute can be set to &lt;em&gt;and&lt;/em&gt; or &lt;em&gt;or&lt;/em&gt;. For &lt;em&gt;and&lt;/em&gt;, every item must cause the sub-elements of the expression to evaluate to &lt;strong&gt;true&lt;/strong&gt;, and for &lt;em&gt;or&lt;/em&gt;, at least one must evaluate to true.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;The &lt;strong&gt;ifEmpty&lt;/strong&gt; attribute can be set to &lt;em&gt;true&lt;/em&gt; or &lt;em&gt;false&lt;/em&gt;. If &lt;em&gt;true&lt;/em&gt;, then the iterate expression will evaluate to &lt;strong&gt;true&lt;/strong&gt; for empty collections, else to &lt;strong&gt;false&lt;/strong&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;See the example under the &lt;a href="#instanceof"&gt;instanceof&lt;/a&gt; section.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="count"&gt;&lt;/a&gt;&lt;h4&gt;Using count&lt;/h4&gt;&lt;br /&gt;The count element's &lt;strong&gt;value&lt;/strong&gt; attribute can take an integer value as parameter if the collection needs to contain the exact number of items. However, the following wildcards are also allowed:&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;*&lt;/td&gt;&lt;td&gt;Any number of items&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;?&lt;/td&gt;&lt;td&gt;Zero or one item&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;One ore more items&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;!&lt;/td&gt;&lt;td&gt;No items&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;See our &lt;a href="#simpleexample"&gt;first simple visibleWhen example&lt;/a&gt; for usage.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="test"&gt;&lt;/a&gt;&lt;h4&gt;Using test&lt;/h4&gt;&lt;br /&gt;Test can be used to evaluate the state (i.e. value) of a specific property of the focussed object. The test expression can evaluate to &lt;strong&gt;true&lt;/strong&gt;, &lt;strong&gt;false&lt;/strong&gt; or &lt;strong&gt;not-loaded&lt;/strong&gt; if the property tester (implemented by a Java class) is not loaded.&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;property&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;specifies the name of the property of the object to test&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;args&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;specifies additional arguments to pass to the property tester&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;value&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;the value we expect the property to be&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;forcePluginActivation&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;if this is set to &lt;strong&gt;true&lt;/strong&gt;, the plugin that contributes the property tester class will be loaded to enable the evaluation, if it is not loaded yet. However, this loading will only happen if the evaluation context used allows plugin activation. What does this mean: do not depend that when you set this flag to true, the plugin containing the property tester code will actually be loaded.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; In a future blog I will discuss how to implement your own property testers; quite a powerful feature. For now, let me just point you to some property testers available for your enjoyment. You can follow the links for the detailed code level information, or else have a look at the Propery Testers section in the &lt;a href="http://wiki.eclipse.org/Command_Core_Expressions" title="Command Core Expressions - Eclipsepedia"&gt;Command Core Expressions&lt;/a&gt; wiki page for a summary.&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.expressions/src/org/eclipse/core/internal/expressions/propertytester/PlatformPropertyTester.java?view=co" title=""&gt;PlatformPropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ResourcePropertyTester.java?view=co" title=""&gt;ResourcePropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/FilePropertyTester.java?view=co" title=""&gt;FilePropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ProjectPropertyTester.java?view=co" title=""&gt;ProjectPropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ResourceMappingPropertyTester.java?view=co" title=""&gt;ResourceMappingPropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.workbench/Eclipse%20UI/org/eclipse/ui/internal/activities/ActivityPropertyTester.java?view=co" title=""&gt;ActivityPropertyTester&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.workbench/Eclipse%20UI/org/eclipse/ui/internal/OpenPerspectivePropertyTester.java?view=co" title=""&gt;OpenPerspectivePropertyTester&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a name="vars"&gt;&lt;/a&gt;&lt;h3&gt;Core Expression Variables&lt;/h3&gt;&lt;br /&gt;I was planning to list the most common variables available for core expressions here and discuss some of them, but time caught up with me. For now I will point you to:&lt;br /&gt;&lt;li&gt;The Variables and the Command Framework section in the &lt;a href="http://wiki.eclipse.org/Command_Core_Expressions" title="Command Core Expressions - Eclipsepedia"&gt;Command Core Expressions&lt;/a&gt; wiki page.&lt;br /&gt;&lt;li&gt;The &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.workbench/Eclipse%20UI/org/eclipse/ui/ISources.java?view=co" title=""&gt;ISources.java&lt;/a&gt; file that list these variables.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt; if you use the &lt;em&gt;selection&lt;/em&gt; variable, you need to make sure the View that you are expecting a selection from is a SelectionProvider for the platform by registering it as a selection provider, e.g. by calling &lt;em&gt;getSite().setSelectionProvider(viewer)&lt;/em&gt;.  &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Coming soon...&lt;/h2&gt;&lt;br /&gt;&lt;li&gt;What about enabling and disabling Commands? (enabledWhen, activeWhen)&lt;br /&gt;&lt;li&gt;More on using object properties to determine visibility and enablement of Commands (propertyTesters)&lt;br /&gt;&lt;li&gt;If you don't like XML: how to tune your Commands from the Java side of things (the programmatic approach)&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=223445"&gt;Eclipse.org Commands Framework Article in bugzilla&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Article on Eclipse Commands Framework&lt;/a&gt;, by Marc R. Hoffmann&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Eclipse.org Wiki on Command Framework&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.vogella.de/articles/EclipseCommands/article.html" title="Using Eclipse Commands with Eclipse Ganymede (3.4) - Tutorial"&gt;Eclipse Commands Tutorial&lt;/a&gt;, by Lars Vogel&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.eclipse.org/Command_Core_Expressions" title="Command Core Expressions - Eclipsepedia"&gt;Eclipse.org Wiki on Core Expressions&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.eclipse.org/Menu_Contributions" title="Menu Contributions - Eclipsepedia"&gt;Eclipse.org Wiki on Menu Contributions&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.eclipse.org/Menus_Extension_Mapping" title="Menus Extension Mapping - Eclipsepedia"&gt;Eclipse.org Wiki on mapping from old to new menu contribution extension points&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Enough said.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-4256722311152948898?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/4256722311152948898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=4256722311152948898' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4256722311152948898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/4256722311152948898'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/06/eclipse-rcp-commands-part-3-visiblewhen.html' title='Eclipse RCP Commands Part 3: visibleWhen and Core Expressions'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-7916780841266653138</id><published>2009-06-01T14:18:00.000-07:00</published><updated>2009-06-01T14:21:24.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='jsp'/><category scheme='http://www.blogger.com/atom/ns#' term='javaEE'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='soap'/><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><category scheme='http://www.blogger.com/atom/ns#' term='servlets'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Archeology of Java</title><content type='html'>When faced with a bulky problem...&lt;br /&gt;&lt;img class="size-full wp-image-19" src="http://blog.richclientgui.com/wp-content/uploads/2009/06/archeology.png" alt="big java web application" width="600" height="264" /&gt;&lt;br /&gt;&lt;br /&gt;you have to start digging.&lt;br /&gt;&lt;img class="size-full wp-image-20" src="http://blog.richclientgui.com/wp-content/uploads/2009/06/archeology2.png" alt="you have to start digging" width="600" height="264" /&gt;&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://aslamkhan.net/"&gt;Aslam Khan&lt;/a&gt; for planting the term "archeology of Java" in a discussion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-7916780841266653138?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/7916780841266653138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=7916780841266653138' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7916780841266653138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7916780841266653138'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/06/archeology-of-java.html' title='Archeology of Java'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-936260591539530488</id><published>2009-06-01T02:47:00.000-07:00</published><updated>2009-06-01T11:00:18.050-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Eclipse RCP Commands API: Review of Part Two</title><content type='html'>&lt;h2&gt;Quick Review: Defining a Command&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;In this blog I just to want review the basic definition of a command by adding an additional Command to the example application using the steps defined in &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands API Part Two"&gt;Part Two&lt;/a&gt; of the series on Eclipse RCP Commands. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We already have an &lt;em&gt;Open eBook&lt;/em&gt; command that we made visible in the &lt;em&gt;File&lt;/em&gt; menu of the &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#example"&gt;MyReader&lt;/a&gt; application. Now we want to add another item to the &lt;em&gt;File&lt;/em&gt; menu, as well as to a context menu, to allow the user to annotate an eBook. Let us call this the &lt;em&gt;Annotate eBook&lt;/em&gt; command. So let us follow the same eight steps we did for the &lt;em&gt;Open eBook&lt;/em&gt; command.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Step 1: Create RCP application&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Done already (I assume you are working from the example in  &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands API Part Two"&gt;Part Two&lt;/a&gt;.)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Step 2: Add &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension to &lt;em&gt;plugin.xml&lt;/em&gt;.&lt;/h3&gt;&lt;br /&gt;Done already. (see &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#step2"&gt;step 2&lt;/a&gt; of previous blog)&lt;br /&gt;&lt;p&gt;&lt;a name="step3"&gt;&lt;/a&gt;&lt;h3&gt;Step 3: Declare &lt;em&gt;Annotate eBook&lt;/em&gt; command.&lt;/h3&gt;&lt;br /&gt; &lt;li&gt;right-click the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension, and select &lt;strong&gt;New -&amp;gt; Command&lt;/strong&gt; from the context menu.&lt;br /&gt; &lt;li&gt;change the &lt;strong&gt;id&lt;/strong&gt; to something like "&lt;em&gt;com.richclientgui.myreader.commands.AnnotateEBook&lt;/em&gt;"&lt;br /&gt; &lt;li&gt;change the &lt;strong&gt;name&lt;/strong&gt; to "&lt;em&gt;Annotate eBook&lt;/em&gt;"&lt;br /&gt; &lt;li&gt;change &lt;strong&gt;description&lt;/strong&gt; to "&lt;em&gt;Annotates the current eBook&lt;/em&gt;"&lt;br /&gt;&lt;/p&gt;  &lt;br /&gt;Our plugin.xml now contains the following entry for the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension:&lt;br&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.commands&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;defaultHandler=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.handlers.DefaultOpenEBookHandler&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;description=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;an&amp;nbsp;eBook&amp;nbsp;file&amp;nbsp;for&amp;nbsp;reading&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;name=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;eBook&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;description=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Annotates&amp;nbsp;the&amp;nbsp;current&amp;nbsp;eBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;name=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Annotate&amp;nbsp;eBook&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Step 4: Add the &lt;em&gt;org.eclipse.ui.menus&lt;/em&gt; extension to &lt;em&gt;plugin.xml&lt;/em&gt;.&lt;/h3&gt;&lt;br /&gt;Done. (see &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#step4"&gt;step 4&lt;/a&gt; of previous blog)&lt;br /&gt;&lt;h3&gt;Step 5: Add the &lt;em&gt;menuContribution&lt;/em&gt; element&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;We want to make our &lt;em&gt;Annotate eBook&lt;/em&gt; command accessible both in the &lt;em&gt;File&lt;/em&gt; menu, and in the context menu of the view. We already declared a &lt;em&gt;menuContribution&lt;/em&gt; for the File menu (see &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#step5"&gt;step 5&lt;/a&gt; of previous blog).&lt;br /&gt;In order to make the command accessible in any context menu, we add a new &lt;em&gt;menuContribution&lt;/em&gt;:&lt;br&gt;&lt;br /&gt;&lt;li&gt; Right-click the org.eclipse.ui.menus extension, and select &lt;strong&gt;New -&amp;gt; menuContribution&lt;/strong&gt; from the context menu&lt;br /&gt;&lt;li&gt; Change the &lt;strong&gt;locationURI&lt;/strong&gt; to &lt;strong&gt;popup:org.eclipse.ui.popup.any?after=additions&lt;/strong&gt; &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Step 6: Add the &lt;em&gt;Annotate eBook&lt;/em&gt; command to the menuContributions.&lt;/h3&gt;&lt;br /&gt;&lt;li&gt; Right-click on the &lt;em&gt;menuContribution&lt;/em&gt; created in step 5, and select &lt;strong&gt;New -&amp;gt; command&lt;/strong&gt; from the context menu.&lt;br /&gt;&lt;li&gt; Change &lt;strong&gt;commandId&lt;/strong&gt; to the &lt;strong&gt;id&lt;/strong&gt; you provided to your Command definition in &lt;a href="#step3"&gt;step 3&lt;/a&gt;.&lt;br /&gt;&lt;li&gt; Change mnemonic to "A" to underline the first letter of "Annotate" as your shortcut mnemonic for your command in the menu.&lt;br /&gt;&lt;li&gt; Repeat the above for the &lt;strong&gt;menu:file?before=quit&lt;/strong&gt; menuContribution element.&lt;br /&gt;&lt;p&gt;But now we have an interesting problem: the client wants the menu item in the &lt;em&gt;File&lt;/em&gt; menu to read "&lt;em&gt;Annotate eBook&lt;/em&gt;", but the context menu's item must read only "&lt;em&gt;Annotate&lt;/em&gt;". If we change the &lt;strong&gt;name&lt;/strong&gt; attribute of the command definition, then it will change in both places. Luckily, the Commands API can help us out here. It is possible to change the presentation of commands for specific menu contributions by "overriding" the text to be used for labels and tooltips. To do this we:&lt;br&gt;&lt;br /&gt;&lt;li&gt;Select the command contribution element under the &lt;strong&gt;popup:org.eclipse.ui.popup.any?after=additions&lt;/strong&gt; menu contribution elment, &lt;br /&gt;&lt;li&gt;and change the value of the &lt;strong&gt;label&lt;/strong&gt; attribute to "Annotate".&lt;br&gt;&lt;br /&gt;Our &lt;em&gt;org.eclipse.ui.menus&lt;/em&gt; extension definition in the &lt;em&gt;plugin.xml&lt;/em&gt; now looks like:&lt;br&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;  &lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.menus&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;menu:file?before=quit&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;O&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;A&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;popup:org.eclipse.ui.popup.any?after=additions&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.AnnotateEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;label=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Annotate&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;A&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Step 7: Change command menu-item placement.&lt;/h3&gt;&lt;br /&gt;Let's assume we are happy with the current placement.&lt;br /&gt;&lt;h3&gt;Step 8: Implement a default Handler&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Let us be lazy again and implement a very basic handler that just opens a message dialog. I will go into more detail about &lt;strong&gt;org.eclipse.core.commands.Handler&lt;/strong&gt; and a future blog. &lt;br /&gt;&lt;li&gt; Implement a class called &lt;strong&gt;DefaultAnnotateEBookHandler&lt;/strong&gt; that extends &lt;strong&gt;AbstractHandler&lt;/strong&gt;, and only override the&lt;strong&gt; execute(...)&lt;/strong&gt; method to call the JFace &lt;em&gt;MessageDialog&lt;/em&gt; class to show some information.&lt;br /&gt;&lt;li&gt; Select the &lt;strong&gt;AnnotateEBookCommand&lt;/strong&gt; definition from &lt;a href="#step3"&gt;step 3&lt;/a&gt; and select the &lt;strong&gt;DefaultAnnotateEBookHandler&lt;/strong&gt; class as the &lt;strong&gt;defaultHandler&lt;/strong&gt;'s value.&lt;br /&gt;The code for &lt;strong&gt;DefaultAnnotateEBookHandler&lt;/strong&gt; looks something like this:&lt;br&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.AbstractHandler;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.ExecutionEvent;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.ExecutionException;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.jface.dialogs.MessageDialog;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.swt.widgets.Display;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;DefaultAnnotateEBookHandler&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;AbstractHandler&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Object&amp;nbsp;execute&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ExecutionEvent&amp;nbsp;event&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throws&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ExecutionException&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;MessageDialog.openInformation&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Display.getDefault&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getActiveShell&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Annotate&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;For&amp;nbsp;now:&amp;nbsp;write&amp;nbsp;in&amp;nbsp;the&amp;nbsp;margins&amp;nbsp;of&amp;nbsp;the&amp;nbsp;real&amp;nbsp;book.&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;null&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Where's that context menu?&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Those of you who have actually been entering the example code, would have found out by now that there is no context showing when running the example. Why not? Well, we have not created a context menu yet for our View. Do that, open the &lt;strong&gt;View&lt;/strong&gt; class created by the &lt;em&gt;New Plug-in Project Wizard&lt;/em&gt; in &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#step1"&gt;step 1&lt;/a&gt; of my previous blog.&lt;br /&gt;Change the code to look like this (basically adding the &lt;strong&gt;createContextMenu()&lt;/strong&gt; method):&lt;br&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;View&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ViewPart&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;final&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;ID&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;MyReader.view&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;TableViewer&amp;nbsp;viewer;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//other&amp;nbsp;code&amp;nbsp;not&amp;nbsp;shown...&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;createPartControl&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Composite&amp;nbsp;parent&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;viewer&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;TableViewer&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;parent,&amp;nbsp;SWT.MULTI&amp;nbsp;|&amp;nbsp;SWT.H_SCROLL&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;|&amp;nbsp;SWT.V_SCROLL&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;viewer.setContentProvider&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ViewContentProvider&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;viewer.setLabelProvider&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ViewLabelProvider&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;viewer.setInput&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;getViewSite&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;createContextMenu&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;createContextMenu&lt;/font&gt;&lt;font color="#000000"&gt;(){&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;final&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;MenuManager&amp;nbsp;mm&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;MenuManager&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;view.popupmenu&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mm.setRemoveAllWhenShown&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mm.addMenuListener&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IMenuListener&lt;/font&gt;&lt;font color="#000000"&gt;(){&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;menuAboutToShow&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;IMenuManager&amp;nbsp;manager&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mm.add&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Separator&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;IWorkbenchActionConstants.MB_ADDITIONS&lt;/font&gt;&lt;font color="#000000"&gt;))&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;})&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;final&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Menu&amp;nbsp;menu&amp;nbsp;=&amp;nbsp;mm.createContextMenu&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;viewer.getTable&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;viewer.getTable&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.setMenu&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;menu&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;getSite&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.registerContextMenu&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;mm,&amp;nbsp;viewer&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you run the &lt;em&gt;MyReader&lt;/em&gt; application now, you should get the context menu when right-clicking in the view, proudly showing your "&lt;em&gt;Annotate&lt;/em&gt;" item.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Feel free to &lt;a href="http://www.richclientgui.com/blogs/eclipsecommands/myreader_sample02.zip" title=""&gt;download the source code&lt;/a&gt; for this blog's example.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Next up&lt;/h2&gt;&lt;br /&gt;&lt;li&gt;Showing commands only when you want to...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=223445"&gt;Eclipse.org Commands Framework Article in bugzilla&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Article on Eclipse Commands Framework&lt;/a&gt;, by Marc R. Hoffmann&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Eclipse.org Wiki on Command Framework&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.vogella.de/articles/EclipseCommands/article.html" title="Using Eclipse Commands with Eclipse Ganymede (3.4) - Tutorial"&gt;Eclipse Commands Tutorial&lt;/a&gt;, by Lars Vogel&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Enough said.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-936260591539530488?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/936260591539530488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=936260591539530488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/936260591539530488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/936260591539530488'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/06/eclipse-rcp-commands-api-review-of-part.html' title='Eclipse RCP Commands API: Review of Part Two'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-7566839983503035912</id><published>2009-05-25T14:47:00.000-07:00</published><updated>2009-06-01T10:56:04.494-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Handler'/><category scheme='http://www.blogger.com/atom/ns#' term='IAction'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='Actions'/><title type='text'>Eclipse RCP Commands API Part Two</title><content type='html'>&lt;p&gt;&lt;br /&gt; This is my second blog about the Eclipse Commands framework, but actually the first one containing useful (I hope) information. I'm going to focus on the topic from a practical "using it in development" point of view, trying to keep the examples as simple as possible and the theory limited. For an updated outline please refer to the first blog in the series: &lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-one.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands API Part One"&gt;Eclipse RCP Commands Part One&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;!--&lt;br /&gt; If you are looking for a detailed discussion on the Commands framework and its design and implementation, history, etc. then I suggest you have a look at the &lt;br /&gt;--&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; &lt;em&gt;Short history&lt;/em&gt;: the Commands framework has been around partially since Eclipse 3.0, maturing over the versions until it became quite useful in Eclipse 3.3. Some refinements in Eclipse 3.4 makes it even more appealing. I must admit, before Eclipse 3.3 I saw no reason for using Commands, and I stuck to using &lt;a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/action/IAction.html" title="IAction (Eclipse Platform API Specification)"&gt;IActions&lt;/a&gt; and &lt;a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/IActionDelegate.html" title="IActionDelegate (Eclipse Platform API Specification)"&gt;IActionDelegates&lt;/a&gt;, trying to work around their issues as much as possible (and falling into the rythm of the copy-and-paste anti-pattern in order to contribute an IActionDelegate to multiple places in a UI). No I'm trying to convince all my clients to "renew" their code to use Commands...&lt;br /&gt;&lt;/p&gt; &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a name="intro"&gt;What are Commands&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; "&lt;i&gt;A command is neither the presentation nor a particular behavior implementation; it is an abstract representation of some semantical behavior.&lt;/i&gt;" - Marc R. Hoffmann (see &lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Article on Eclipse Commands Framework&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; That's the best quote I could find as to what a Command is. What does it boil down to? I assume (hope?) you are all familiar with the &lt;a href="http://en.wikipedia.org/wiki/Model_view_controller" title="Model–view–controller - Wikipedia, the free encyclopedia"&gt;Model-View-Controller&lt;/a&gt; pattern, used especially when developing UI applications. By abstracting a particular piece of functionality into separate Model, View and Controller objects, the code is must less coupled, allowing more (and easier) reuse, flexibility and extensibility. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; Well, the Command design is not exactly MVC, but it has the same goals in mind. It abstracts the actual business or application semantics (i.e. what is actually meant to happen from business or application functionality perspective) into this thing called a Command. Worries about how it should appear in the UI (menu contributions), or what exactly must happen on a code implementation level to execute the command (handlers) is left for later. In this way we get the same decoupling of presentation and implementation as with MVC, and thus the gain in reusability of Commands and their handlers, and increase in the flexibility and extensibility of the code, thus leading overall to code that is much easier to maintain. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; Add to the above paragraph that code that is easier to maintain leads to huge development cost savings, and you'll have a convincing argument to offer to your boss for allowing you to refactor away all the old IActionDelegates.  &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Ok, but what to we do with Commands?&lt;/h4&gt;&lt;br /&gt;Plain and simple: we use it to implement functions that our application can perform and make it available as menu or toolbar items so the user can invoke it.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;On a more practical level&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;That is about enough theory for one day. Let's get down to the bits and the bytes. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="example"&gt;The Example&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Firstly, I want to introduce my patent-pending idea for an application. Image this: you have this cross-platform application (obviously implemented using Eclipse RCP) that can actually read electronic versions of books, that we can call "e-books". "Wow!" you say. "Amazing". "What a novel idea". &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Let us call our bleeding edge application &lt;em&gt;MyReader&lt;/em&gt;. You can &lt;a href="http://www.richclientgui.com/blogs/eclipsecommands/myreader_sample01.zip"&gt;download&lt;/a&gt; the source code for this blog's version of the example.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="step1"&gt;&lt;/a&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Create a RCP application using Eclipse 3.4 (I'm using 3.4.1) and the &lt;em&gt;New Plug-in Project&lt;/em&gt; wizard. &lt;br/&gt;&lt;br /&gt; &lt;li&gt; Name the project &lt;em&gt;MyReader&lt;/em&gt;&lt;br /&gt; &lt;li&gt; On the next wizard page fill in the details you want, but make sure "&lt;em&gt;Would you like to create a rich client application&lt;/em&gt;" is set to "&lt;em&gt;Yes&lt;/em&gt;".&lt;br /&gt; &lt;li&gt; On the third wizard page, select the "&lt;em&gt;RCP application with a view&lt;/em&gt;" as the template to use.&lt;br /&gt; &lt;li&gt; Run the resulting RCP application to make sure it runs, so you don't blame my examples later for messing up your pristine code.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we have the example application that we are going to enable with Commands. Exciting, isn't it?&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How to define a Command&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;To have a command that is actually accessible in the UI, and able to do something, we need 3 "components":&lt;br/&gt;&lt;br /&gt; &lt;li&gt;The Intent: the Command declaration&lt;br /&gt; &lt;li&gt;The Presentation: the menu contribution declaration(s)&lt;br /&gt; &lt;li&gt;The Behaviour: the Handler that implements the behaviour of the Command&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="definecommand"&gt;Declaring the Command (Intent)&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;We declare the Command using the &lt;a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_ui_commands.html" title="Commands"&gt;org.eclipse.ui.commands&lt;/a&gt; extension point. I'm sure you remember this command we declare indicates the meaning or intent of the functionality we want to add to our application or plugin.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Let us explore this Command declaration in our example, and then I'll discuss what is going on.&lt;br /&gt; We need to open an ebook file with our application, so we will define a command to do this.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; &lt;strong&gt;&lt;a name="step2"&gt;&lt;/a&gt;Step 2&lt;/strong&gt;: Add the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension to our &lt;em&gt;plugin.xml&lt;/em&gt;&lt;br/&gt;&lt;br /&gt; &lt;li&gt; Open the PDE-Editor (Plugin Editor), if it is not open already, and select the &lt;strong&gt;Extensions&lt;/strong&gt; tab. (You double-click the plugin.xml or MANIFEST.MF files in the project. However, if you did not know that, you must maybe first implement a "Hello RCP World" application before jumping to Commands...)&lt;br /&gt;  &lt;li&gt; If, due to random bit-changes caused by unexplained solar activity, you already have the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension in your list of extensions, then do not follow the rest of this step.&lt;br /&gt; &lt;li&gt; Click on the "&lt;strong&gt;Add...&lt;/strong&gt;" button.&lt;br /&gt; &lt;li&gt; Start typing in "&lt;strong&gt;org.eclipse.ui.commands&lt;/strong&gt;", and select it from the filtered list when you see it. If it is not available uncheck the "&lt;em&gt;Show only extension points from required plug-ins&lt;/em&gt;" option.&lt;br /&gt; &lt;li&gt; Select the &lt;strong&gt;Finish&lt;/strong&gt; button. This will add the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; entry to your &lt;em&gt;plugin.xml&lt;/em&gt; file.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;a name="step3"&gt;&lt;/a&gt;Step 3&lt;/strong&gt;: Declare the Open File command&lt;br/&gt;&lt;br /&gt;&lt;li&gt;right-click the &lt;em&gt;org.eclipse.ui.commands&lt;/em&gt; extension, and select &lt;strong&gt;New -&gt; Command&lt;/strong&gt; from the context menu.&lt;br /&gt;&lt;li&gt;change the &lt;strong&gt;id&lt;/strong&gt; to something like "&lt;em&gt;mydomain.myreader.commands.OpenEBook&lt;/em&gt;"&lt;br /&gt;&lt;li&gt;change the &lt;strong&gt;name&lt;/strong&gt; to "&lt;em&gt;Open eBook&lt;/em&gt;"&lt;br /&gt;&lt;li&gt;change &lt;strong&gt;description&lt;/strong&gt; to "&lt;em&gt;Opens an eBook file for reading&lt;/em&gt;"&lt;br /&gt;&lt;li&gt;for now, ignore the rest&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;Steps 2 and 3 updates the &lt;em&gt;plugin.xml&lt;/em&gt; file of the plugin project by adding the necessary extension point and declaring a basic command. The plugin.xml file now contains:&lt;br /&gt;  &lt;style type="text/css"&gt;&lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;  &lt;/style&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt;&lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt;&lt;div align="left" class="java"&gt;&lt;br /&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.commands&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;description=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;an&amp;nbsp;eBook&amp;nbsp;file&amp;nbsp;for&amp;nbsp;reading&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;name=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;eBook&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;/td&gt;&lt;br /&gt;  &lt;!-- end source code --&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt;&lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Congratulations! Your first command. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;"But if I run my app, I don't see this command. What's wrong?" Nothing. We still need to define how this command will be visible in the UI, and what the behavior should be when this command is invoked. As mentioned earlier, these are decoupled from the Command declaration.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;However, let us first examine the declaration in the plugin.xml. The org.eclipse.ui.commands extension allows us to declare, among other things, a Command. The Command definition needs the following attributes:&lt;br&gt;&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;a unique id that will be used for referring to this command when declaring the UI contributions and Handlers&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;name&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;a user-readable name that will be used for the label in the menu contribution(s), if the menu contribution does not define its own label&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;description&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;a user-readable name that will be used for the tooltip in the menu contribution(s), if the contribution does not define its own description&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We are still going to have a look at some of the other attributes available. If you can't wait, go and see &lt;a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_ui_commands.html" title="Commands"&gt;org.eclipse.ui.commands&lt;/a&gt; for more detailed information about the extension point definition. Go on, don't mind me. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: here we had a look at how to declare commands using the extension point in the plugin.xml file. In a later blog I plan to discuss how to do it programmatically. I will update this section with a link to that blog as soon as it is available.&lt;/em&gt;&lt;br /&gt; &lt;!--&lt;br /&gt;  TODO update with link to programmatic declaration blog&lt;br /&gt; --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="menucontribution"&gt;Basic menu contribution (Presentation)&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;It is time to get his command to be presented in the UI of the application. I assume you have already done some nice UI design work sessions with your potential end-users and you are ready to build the ultimate user friendly intuitive graphical user interface for your application. For our example we are just going to use the UI-design-by-coincidence approach and just add our stuff and see how it looks. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In order to contribute an item that will invoke a Command to the UI, we need to add the &lt;a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_ui_menus.html" title="Help - Eclipse SDK"&gt;org.eclipse.ui.menus&lt;/a&gt; extension to our &lt;em&gt;plugin.xml&lt;/em&gt;, and declare a &lt;em&gt;MenuContribution&lt;/em&gt; element followed by a &lt;em&gt;Command&lt;/em&gt; element.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We first declare where (i.e. the main menubar or toolbar, or a view or editor specific menu and/or toolbar, or a context menu) the command should be added via the &lt;em&gt;MenuContribution&lt;/em&gt;. Then we declare the visual representation of our Command using the MenuContribution's &lt;em&gt;Command&lt;/em&gt; element.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="step4"&gt;&lt;/a&gt;&lt;strong&gt;Step 4&lt;/strong&gt;:Add the &lt;em&gt;org.eclipse.ui.menus&lt;/em&gt; extension to &lt;em&gt;plugin.xml&lt;/em&gt;&lt;br/&gt;&lt;br /&gt;&lt;li&gt; Click on the &lt;strong&gt;Add...&lt;/strong&gt; button in the Plugin Editor.&lt;br /&gt;&lt;li&gt; Select the org.eclipse.ui.menus extension from the list of available extensions. If it is not available uncheck the "&lt;em&gt;Show only extension points from required plug-ins&lt;/em&gt;" option.&lt;br /&gt;&lt;li&gt; Select the Finish button. This will add the &lt;em&gt;org.eclipse.ui.menus&lt;/em&gt; extension to the &lt;em&gt;plugin.xml&lt;/em&gt; file.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="step5"&gt;&lt;/a&gt;&lt;strong&gt;Step 5&lt;/strong&gt;: Add the &lt;em&gt;MenuContribution&lt;/em&gt; element&lt;br/&gt;&lt;br /&gt;&lt;li&gt; Right-click the org.eclipse.ui.menus extension, and select &lt;strong&gt;New -&gt; menuContribution&lt;/strong&gt; from the context menu&lt;br /&gt;&lt;li&gt; Change the &lt;strong&gt;locationURI&lt;/strong&gt; to &lt;strong&gt;menu:file?after=additions&lt;/strong&gt; (don't worry, we'll discuss it just now)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="step6"&gt;&lt;/a&gt;&lt;strong&gt;Step 6&lt;/strong&gt;: Add the &lt;em&gt;Command&lt;/em&gt; to the MenuContribution&lt;br/&gt;&lt;br /&gt;&lt;li&gt; Right-click on the &lt;em&gt;menuContribution&lt;/em&gt; created in step 5, and select &lt;strong&gt;New -&gt; command&lt;/strong&gt; from the context menu.&lt;br /&gt;&lt;li&gt; Change &lt;strong&gt;commandId&lt;/strong&gt; to the &lt;strong&gt;id&lt;/strong&gt; you provided to your Command definition in &lt;a href="#step3"&gt;step 3&lt;/a&gt;.&lt;br /&gt;&lt;li&gt; Change mnemonic to "O" to underline the first letter of the "Open" as your shortcut mnemonic for your command in the menu.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I'm sure you are eager to run your MyReader app now. Go ahead, please. Do you see it? A grayed-out &lt;em&gt;Open eBook&lt;/em&gt; menu-item just underneath &lt;em&gt;Exit&lt;/em&gt; in the &lt;em&gt;File&lt;/em&gt; menu.&lt;br /&gt;&lt;img src="http://www.richclientgui.com/blogs/eclipsecommands/firstmenucontribution.png" alt="First Menu Contribution with grayed-out Open eBook Command" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;That is not quite what we intended. We'll get there, though. First a discussion on what we actually did.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We first needed to add the &lt;em&gt;org.eclipse.ui.menus&lt;/em&gt; extension to our plugin, and then we declared that we want to contribute an item to a menu via the &lt;em&gt;MenuContribution&lt;/em&gt; element. We only had to specify one attribute: the &lt;em&gt;locationURI&lt;/em&gt;. More on that in the next &lt;a href="#location"&gt;section&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We then declared that we are actually contributing a &lt;em&gt;Command&lt;/em&gt; item as part of our MenuContribution. This is not the actual definition of a Command, but just an element indicating that we wish to represent the command with the identifier specified in &lt;strong&gt;commandId&lt;/strong&gt; as an item in the menu or toolbar that we are declaring this MenuContribution for. Thus by specifying the locationURI "&lt;em&gt;menu:file?after=additions&lt;/em&gt;" and the commandId "&lt;em&gt;com.richclientgui.myreader.commands.OpenEBook&lt;/em&gt;" we are saying that we want the &lt;em&gt;OpenEBook&lt;/em&gt; command to display in the standard &lt;em&gt;File&lt;/em&gt; menu after the &lt;em&gt;additions&lt;/em&gt; placeholder.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The &lt;strong&gt;mnemonic&lt;/strong&gt; attribute indicates what character should be underlined and act as a shortcut key for selecting the menu item, if that menu is currently open. Other additional attributes can be specified to manage the presentation of the Command in the menu, e.g. the icon, label (overriding the value set in the Command's &lt;strong&gt;name&lt;/strong&gt; attribute), tooltip (overriding the value set in the Command's &lt;strong&gt;description&lt;/strong&gt; attribute), etc. This gives us the flexibility to present the same Command slightly different depending on where it gets contributed, something that is not possible with IActions and IActionDelegates.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="location"&gt;LocationURI&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;The locationURI is an interesting attribute: it allows the developer to use a URI string to specify where a specific contribution (whether it is a command item, a submenu or some other widget that can be contributed) must be added. It is of the form:&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;[scheme]:[id]?[placement arguments]&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;scheme&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The scheme indicates the type of the target component of the contribution, and can be one of: &lt;br /&gt;  &lt;li&gt; &lt;em&gt;menu&lt;/em&gt; : either main menu or view menu&lt;br /&gt;  &lt;li&gt; &lt;em&gt;toolbar&lt;/em&gt; : either main toolbar or view toolbar&lt;br /&gt;  &lt;li&gt; &lt;em&gt;popup&lt;/em&gt; : context menu&lt;br /&gt;  &lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The unique identifier of the menu, toolbar or context (popup) menu where the contribution must be added. See the &lt;a href="#standardids"&gt;list&lt;/a&gt; below for standard platform identifiers that can be used.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;&lt;strong&gt;placement&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The arguments helps to define the placement of the contribution items in relation to another item or placeholder (i.e. GroupMarker) in the target menu. It consists of either the word "&lt;em&gt;before&lt;/em&gt;" or "&lt;em&gt;after&lt;/em&gt;" followed by an equal sign (&lt;em&gt;=&lt;/em&gt;) and then the identifier of a menu contribution item. The word "&lt;em&gt;additions&lt;/em&gt;" can also be used in place of an identifier. Contributions added to "&lt;em&gt;additions&lt;/em&gt;" will typically be placed last in a menu. &lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br/&gt;&lt;br /&gt;&lt;p&gt;Talking in detail about the locationURI and menu contribution placement can be a long blog entry on its own, so I want to come to this subject in more detail later in the series.&lt;br /&gt;&lt;/p&gt; &lt;br /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: I usually declare my view's identifier as the same as the fully qualified Java class name of the ViewPart implementation class, and then use the convention &lt;strong&gt;viewID.menu&lt;/strong&gt;, &lt;strong&gt;viewID.toolbar&lt;/strong&gt; and &lt;strong&gt;viewID.popup&lt;/strong&gt; as identifiers for its various menus. E.g. a View implemented in the class &lt;strong&gt;com.richclientgui.myreader.BookView&lt;/strong&gt; will have the Id &lt;strong&gt;com.richclientgui.myreader.BookView&lt;/strong&gt; and the menu IDs &lt;strong&gt;com.richclientgui.myreader.BookView.menu&lt;/strong&gt;, &lt;strong&gt;com.richclientgui.myreader.BookView.toolbar&lt;/strong&gt; and &lt;strong&gt;com.richclientgui.myreader.BookView.popup&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="standardids"&gt;Platform Menu IDs&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Some standard identifiers are available for commonly used menus and toolbars:&lt;br /&gt;&lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt; &lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;org.eclipse.ui.main.menu&lt;/td&gt;&lt;td&gt;the main Eclipse application menubar&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;org.eclipse.ui.main.toolbar&lt;/td&gt;&lt;td&gt;the main Eclipse application toolbar&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;org.eclipse.ui.popup.any&lt;/td&gt;&lt;td&gt;contributions using this identifier will be visible in all context menus of the application (well, that's not the full truth, but that is a topic for another blog)&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;menu:file&lt;/td&gt;&lt;td&gt;three guesses what menu this one point to...&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;menu:help&lt;/td&gt;&lt;td&gt;I'm not even going to say its a menu, and you only get one guess&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;menu:window&lt;/td&gt;&lt;td&gt;Ok, you start to get the picture&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;helpEnd&lt;/td&gt;&lt;td&gt;name of group-marker at end of &lt;em&gt;Help&lt;/em&gt; menu&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;td&gt;quit&lt;/td&gt;&lt;td&gt;id of &lt;em&gt;Exit&lt;/em&gt; action&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;See &lt;a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_ui_menus.html" title="Help - Eclipse SDK"&gt;IIDEActionConstants&lt;/a&gt; and &lt;a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/IWorkbenchActionConstants.html" title="Help - Eclipse SDK"&gt;IWorkbenchActionConstants&lt;/a&gt; for more useful identifiers.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I can't wait to move that &lt;em&gt;Open eBook&lt;/em&gt; item to the top of the menu...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;a name="step7"&gt;&lt;/a&gt;Step 7&lt;/strong&gt;: Change Command menu-item placement&lt;br /&gt;&lt;li&gt; Select the &lt;em&gt;menuContribution&lt;/em&gt; element we specified in &lt;a href="#step6"&gt;step 6&lt;/a&gt;.&lt;br /&gt;&lt;li&gt; Change the &lt;strong&gt;locationURI&lt;/strong&gt; to be &lt;strong&gt;menu:file?before=quit&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Running our latest version gives us a still grayed-out item, but at least where we want it.&lt;br/&gt; &lt;br /&gt;&lt;img src="http://www.richclientgui.com/blogs/eclipsecommands/intherightplace.png" alt="Open eBook Command in right place" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And our plugin.xml has grown a bit:&lt;br /&gt;   &lt;style type="text/css"&gt;&lt;br /&gt;     &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;   &lt;/style&gt;&lt;br /&gt; &lt;!-- ======================================================== --&gt;&lt;br /&gt; &lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt; &lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt; &lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt; &lt;div align="left" class="java"&gt;&lt;br /&gt; &lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;   &lt;!-- start source code --&gt;&lt;br /&gt;    &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;     &lt;code&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.commands&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;description=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;an&amp;nbsp;eBook&amp;nbsp;file&amp;nbsp;for&amp;nbsp;reading&amp;#34;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;id=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;name=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Open&amp;nbsp;eBook&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;extension&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;point=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;org.eclipse.ui.menus&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;menuContribution&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;locationURI=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;menu:file?before=quit&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;command&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;commandId=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;com.richclientgui.myreader.commands.OpenEBook&amp;#34;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;mnemonic=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;O&amp;#34;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;style=&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;push&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/command&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/menuContribution&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;lt;/extension&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;&lt;br /&gt;   &lt;!-- end source code --&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt; &lt;/table&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt; &lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt; &lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now to implement the behaviour.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="definehandler"&gt;Simple Handler (Behaviour)&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;After all this build-up, it is quite simple to actually add behaviour to a Command. You need to&lt;br /&gt;&lt;li&gt; implement a class that extends &lt;strong&gt;org.eclipse.core.commands.AbstractHandler&lt;/strong&gt;,&lt;br /&gt;&lt;li&gt; and update your Command's &lt;strong&gt;defaultHandler&lt;/strong&gt; attribute that you left empty in &lt;a href="#step3"&gt;step 3&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a name="step8"&gt;&lt;/a&gt;&lt;strong&gt;Step 8&lt;/strong&gt;: Implement a default Handler&lt;br /&gt;&lt;li&gt; Implement a class called &lt;strong&gt;DefaultOpenEBookHandler&lt;/strong&gt; that extends &lt;strong&gt;AbstractHandler&lt;/strong&gt;, and only override the&lt;strong&gt; execute(...)&lt;/strong&gt; method. I just added a call to the JFace &lt;em&gt;MessageDialog&lt;/em&gt; class to show some information. I will discuss these Handler classes more in a future blog in the series. &lt;br /&gt;&lt;li&gt; Select the &lt;strong&gt;OpenEBookCommand&lt;/strong&gt; definition from &lt;a href="#step3"&gt;step 3&lt;/a&gt; and select the &lt;strong&gt;DefaultOpenEBookHandler&lt;/strong&gt; class as the &lt;strong&gt;defaultHandler&lt;/strong&gt;'s value.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; Here is my &lt;strong&gt;DefaultOpenEBookHandler&lt;/strong&gt; class:&lt;br /&gt;   &lt;style type="text/css"&gt;&lt;br /&gt;     &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;   &lt;/style&gt;&lt;br /&gt;&lt;br /&gt; &lt;!-- ======================================================== --&gt;&lt;br /&gt; &lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;br /&gt; &lt;!-- =   Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard  markus@jave.de   = --&gt;&lt;br /&gt; &lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;br /&gt; &lt;div align="left" class="java"&gt;&lt;br /&gt; &lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;   &lt;!-- start source code --&gt;&lt;br /&gt;    &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;     &lt;code&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;package&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;com.richclientgui.myreader.handlers;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.AbstractHandler;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.ExecutionEvent;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.core.commands.ExecutionException;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.jface.dialogs.MessageDialog;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;org.eclipse.swt.widgets.Display;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;DefaultOpenEBookHandler&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;extends&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;AbstractHandler&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Object&amp;nbsp;execute&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ExecutionEvent&amp;nbsp;event&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throws&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ExecutionException&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;MessageDialog.openInformation&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Display.getDefault&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getActiveShell&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;O&amp;nbsp;no!&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;I'm&amp;nbsp;not&amp;nbsp;ready&amp;nbsp;yet.&amp;nbsp;Go&amp;nbsp;read&amp;nbsp;the&amp;nbsp;hardcopy&amp;nbsp;book.&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;return&amp;nbsp;null&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt; &lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;&lt;br /&gt;   &lt;!-- end source code --&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt; &lt;/table&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt; &lt;!-- =       END of automatically generated HTML code       = --&gt;&lt;br /&gt; &lt;!-- ======================================================== --&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you run the application now, you will actually see that the command item in the menu is enabled, and you should see a dialog with a message if you select the item.&lt;br&gt;&lt;br /&gt;&lt;img src="http://www.richclientgui.com/blogs/eclipsecommands/dialog.png" alt="Open eBook Command shows dialog" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;a name="sum"&gt;The Sum of the Parts&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;We saw a basic introduction of how to:&lt;br /&gt;&lt;li&gt; declare a Command&lt;br /&gt;&lt;li&gt; contribute that command to the main menu-bar&lt;br /&gt;&lt;li&gt; define a class that encapsulated the behaviour of the Command&lt;br /&gt;&lt;/p&gt; &lt;br /&gt;&lt;p&gt;Each of these components on their own does not add value to an application, but together it forms a powerful yet flexible and very maintainable Commands framework, far superior to using IActions and IActionDelegates because of the separation between the intent, presentation and behaviour. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Summary of Steps&lt;/h4&gt;&lt;br /&gt; &lt;table border="0" cellspacing="5" cellpadding="5"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step1"&gt;Step 1&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Create sample RCP application&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step2"&gt;Step 2&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Add the org.eclipse.ui.commands extension to our plugin.xml&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step3"&gt;Step 3&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Declare the Open File command&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step4"&gt;Step 4&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Add the org.eclipse.ui.menus extension to plugin.xml&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step5"&gt;Step 5&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Add the MenuContribution element&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step6"&gt;Step 6&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Add the Command to the MenuContribution&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step7"&gt;Step 7&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Change Command menu-item placement&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;td&gt;&lt;a href="#step8"&gt;Step 8&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Implement a default Handler&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt; &lt;/table&gt;&lt;br /&gt; You can &lt;a href="http://www.richclientgui.com/blogs/eclipsecommands/myreader_sample01.zip"&gt;download&lt;/a&gt; the source code for this blog's version of the example.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt; TODO discuss, maybe with diagram, how all work together&lt;br /&gt;--&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Next Episode&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Do not miss out on the next exciting episode on Eclipse RCP Commands. There I'll be tackling mind-blowing topics, like&lt;br /&gt;&lt;li&gt; how to show commands only when you want to&lt;br /&gt;&lt;li&gt; how to disable commands&lt;br /&gt;&lt;li&gt; dynamic menu contributions&lt;br /&gt;&lt;li&gt; handling the Handlers&lt;br /&gt;(Time and weather permitting.)&lt;br /&gt;&lt;/p&gt; &lt;br /&gt;&lt;!--&lt;br /&gt; TODO in next blog: more advanced topics &lt;br /&gt;--&gt;&lt;br /&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=223445"&gt;Eclipse.org Commands Framework Article in bugzilla&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Article on Eclipse Commands Framework&lt;/a&gt;, by Marc R. Hoffmann&lt;br /&gt; &lt;li&gt;&lt;a href="http://svn2.assembla.com/svn/eclipsecommands/trunk/EclipseCommands/contents/article.html" title="The Eclipse RCP Command Framework"&gt;Eclipse.org Wiki on Command Framework&lt;/a&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://www.vogella.de/articles/EclipseCommands/article.html" title="Using Eclipse Commands with Eclipse Ganymede (3.4) - Tutorial"&gt;Eclipse Commands Tutorial&lt;/a&gt;, by Lars Vogel&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Enough said for now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-7566839983503035912?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/7566839983503035912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=7566839983503035912' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7566839983503035912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/7566839983503035912'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html' title='Eclipse RCP Commands API Part Two'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-6698664660816035176</id><published>2009-05-21T14:05:00.000-07:00</published><updated>2009-06-03T08:34:38.925-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='visibleWhen'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='Actions'/><title type='text'>Eclipse RCP Commands API Part One: Outline</title><content type='html'>&lt;p&gt;I've been looking around on the web for information on how to use the &lt;a href="http://www.eclipse.org"&gt;Eclipse&lt;/a&gt; 3.4 Commands API (well, rather Eclipse 3.3 Commands API, 3.4 only fine-tuned it a bit), but could not find much. Since I became disillusioned with &lt;a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/IActionDelegate.html" title="IActionDelegate (Eclipse Platform API Specification)"&gt;IActionDelegates&lt;/a&gt; and started using &lt;a href="http://wiki.eclipse.org/Platform_Command_Framework" title="Platform Command Framework - Eclipsepedia"&gt;Commands&lt;/a&gt; more and more, I've also started having to explain what's going on to a number of people, so I decided to rather write a series of blogs on the topic, and maybe publish the thing as some full-fledged article some day.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So here is the outline I thought of following in my series of blogs:&lt;br /&gt;(I'll update this with links to the relevant blogs as I go on.)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#intro"&gt;What are Commands?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#example"&gt;Example Background&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Defining a Command&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#definecommand"&gt;Command&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Declare Open eBook command&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#menucontribution"&gt;Adding to the UI&lt;/a&gt; (Menubar, toolbar or context menus)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Add to menu&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Add to toolbar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-two.html#definehandler"&gt;Handler&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Define and implement Handler&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Problems with IActionDelegates and how Commands solve it&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Advanced Command topics&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Declaring Commands programmatically&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://hermanlintvelt.blogspot.com/2009/06/eclipse-rcp-commands-part-3-visiblewhen.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands Part 3: visibleWhen and Core Expressions"&gt;Do show or not to show: isVisibleWhen&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://hermanlintvelt.blogspot.com/2009/06/eclipse-rcp-commands-part-3-visiblewhen.html" title="Java, Mac, Software and other kaos: Eclipse RCP Commands Part 3: visibleWhen and Core Expressions"&gt;Using Core Expressions&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;propertyTester&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Setting visibility programmatically&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Enablement of Commands&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Declaratively&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Programmatically&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dynamic Menu contributions&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Binding to keystrokes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CommandParameters&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I'll be going as fast as (available) time allows to complete these various topics around Commands, and the outline will probably change as I go, but hey, that's what being Agile is all about. You are of course extremely welcome to give input as to what information you would like to see, or even provide valuable insight into the topic. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;In the end I want to capture all of this in a proper article (must still decide between using LaTeX or Docbook with TextMate...), if there is enough interest. Please indicate with a comment or a tweet if you're interested in a full article.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Enough said for now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-6698664660816035176?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/6698664660816035176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=6698664660816035176' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6698664660816035176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/6698664660816035176'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/05/eclipse-rcp-commands-api-part-one.html' title='Eclipse RCP Commands API Part One: Outline'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-3769733751864309695</id><published>2009-05-19T12:08:00.001-07:00</published><updated>2009-05-19T12:08:11.142-07:00</updated><title type='text'>The Tools I Use</title><content type='html'>&lt;p&gt;I started this entry on my mobile phone, as a way of testing a new modile blogging app. Might increase my blogging frequency. Hmmm, perhaps not. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Posted with &lt;a href='http://lifecast.sleepydog.net'&gt;LifeCast&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-3769733751864309695?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/3769733751864309695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=3769733751864309695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/3769733751864309695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/3769733751864309695'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2009/05/tools-i-use.html' title='The Tools I Use'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-895709306256752754</id><published>2008-07-22T11:53:00.001-07:00</published><updated>2008-07-22T12:12:32.052-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='NatTable'/><category scheme='http://www.blogger.com/atom/ns#' term='Table'/><title type='text'>SWT Table performance</title><content type='html'>I recently discovered a extremely tuned custom SWT Table widget called &lt;a href="http://nattable.org/"&gt;NatTable&lt;/a&gt;. It is very good at handling large data sets, much better than even the latest Eclipse 3.4 version of the normal SWT &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Table&lt;/span&gt; widget.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To give you some indication, I created a Eclipse RCP application that has two views, each loading the same 1 million domain objects (a simple POJO with some 15 properties, of which only 6 gets displayed in the table as columns) into a normal SWT Table and a NatTable respectively.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Performance&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The difference in performance (over multiple runs) is mind-blowing:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;SWT Table&lt;/span&gt; took on average &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;57 seconds&lt;/span&gt; to load these entries and display the table. And that was with only one column and no column header displayed. (I decided to keep the SWT table as simple as possible, as I was trying out NatTable's API).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;NatTable&lt;/span&gt; took on average &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;4,5 seconds&lt;/span&gt; to load. Yes, four-and-a-half seconds!. That is less than a tenth of the time it took for the SWT Table. And in the NatTable view I had 6 columns, with alternating row colours. In addition the NatTable's columns were all movable and had a custom column-header renderer. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Memory Usage&lt;/span&gt;&lt;/div&gt;&lt;div&gt;It does not stop at performance. I also tested the app's memory usage (loading only a single View at a time) . After doing a System.gc(), the app with only the normal SWT &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Table&lt;/span&gt; widget in a View (loaded with 1 million entries) was using on average &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;430Mb &lt;/span&gt;of memory. &lt;/div&gt;&lt;div&gt;The &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;NatTable&lt;/span&gt; version was using only &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;300Mb&lt;/span&gt; of memory.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm busy moving my implementation over to using &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;NatTable&lt;/span&gt;... will you?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-895709306256752754?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/895709306256752754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=895709306256752754' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/895709306256752754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/895709306256752754'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2008/07/swt-table-performance.html' title='SWT Table performance'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-2139048021069468427</id><published>2008-07-19T15:11:00.000-07:00</published><updated>2008-07-21T03:04:26.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='richclientgui'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='validation'/><title type='text'>Adding Eclipse SWT input validation the easy way</title><content type='html'>&lt;p&gt;Any input provided by a user in a GUI application must typically be validated in ne way or another. There is a number of ways this gets done, while some applications have just ignored the matter alltogether.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;When crafting an Eclipse RCP application, there are some help provided by SWT and JFace. We can add &lt;b&gt;ModifyListener&lt;/b&gt;s and &lt;b&gt;VerifyListener&lt;/b&gt;s to certain SWT widgets. JFace also provides &lt;b&gt;ControlDecoration&lt;/b&gt;s to help us indicate to the user where a problem with a specific input value exists.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The problem is that these are at a low level, and we need to do a lot of "monkey"-coding just to add basic validation and error indication to a widget, and then we're not even touching the world of input masks. If you're like me, you want to concentrate on solving your business problem, and don't want to write lots of basic UI code over and over.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is where the &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;RCP Toolbox&lt;/a&gt; is very useful. It provides a light-weight validation framework (among other features) that makes it much easier to add validation and input masks to SWT &lt;b&gt;Text&lt;/b&gt;, &lt;b&gt;Combo&lt;/b&gt; and &lt;b&gt;CCombo&lt;/b&gt; widgets.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;The goal&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Let us have a look at how to define a basic wizard for creating a new Booking. This wizard must capture the following fields from the user:&lt;/p&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Name&lt;/b&gt;: the name of the booking, typically the name of the person making the booking. May not be empty, and preferably not less than three characters.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Date&lt;/b&gt;: the date and time of the booking. Must be any time from the current time to the end of the year.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Number of Persons&lt;/b&gt;: the number of persons to book for. Must be a number from 1 to 10.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Telephone Number&lt;/b&gt;: the telephone number of the person making the booking. Must be in the form &lt;i&gt;+(country code) (area code) number&lt;/i&gt;, e.g. +44 (33) 555-1111.&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="http://www.richclientgui.com/images/large/Validation.jpg" alt="Validated Wizard" /&gt;&lt;br /&gt;&lt;p&gt;And of course we want indicators next to each field when an error or warning condition exists in the field, as well as a message being written to the &lt;b&gt;WizardDialog&lt;/b&gt;'s message area. For fun we want the user to be able to get a quick-fix option on the date field for setting it to the current time.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;The Validation framework&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;The &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;RCP Toolbox&lt;/a&gt; provides a number of custom widgets and a easy to use validation framework. Adding validation starts with the &lt;b&gt;ValidationToolkit&lt;/b&gt; class. This class gets instantiated to work with a specific type of contents, and is then used to create &lt;b&gt;ValidatingField&lt;/b&gt; instances that can handle that type of contents.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The rest of the framework deals with interfaces and default implementations to facilitate the validation of contents, definition of input masks, provision of quick-fixes, error-handling and conversion of the input text to specific class types.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;The WizardPage and the ValidationToolkits&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;We start by first defining our &lt;b&gt;BookingWizardPage&lt;/b&gt; class and instantiating the necessary &lt;b&gt;ValidationToolkit&lt;/b&gt; instances.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;//Not all imports are shown&lt;br /&gt;import com.richclientgui.toolbox.validation.IFieldErrorMessageHandler;&lt;br /&gt;import com.richclientgui.toolbox.validation.ValidationToolkit;&lt;br /&gt;import com.richclientgui.toolbox.validation.converter.DateStringConverter;&lt;br /&gt;import com.richclientgui.toolbox.validation.converter.IntegerStringConverter;&lt;br /&gt;import com.richclientgui.toolbox.validation.string.StringValidationToolkit;&lt;br /&gt;&lt;br /&gt;public class BookingWizardPage extends WizardPage {&lt;br /&gt;private static final int DECORATOR_POSITION = SWT.TOP | SWT.LEFT;&lt;br /&gt;private static final int DECORATOR_MARGIN_WIDTH = 1;&lt;br /&gt;private static final int DEFAULT_WIDTH_HINT = 150;&lt;br /&gt;&lt;br /&gt;private StringValidationToolkit strValToolkit = null;&lt;br /&gt;private ValidationToolkit&lt;date&gt; dateValToolkit = null;&lt;br /&gt;private ValidationToolkit&lt;integer&gt; intValToolkit = null;&lt;br /&gt;&lt;br /&gt;private final IFieldErrorMessageHandler errorMessageHandler;&lt;br /&gt;&lt;br /&gt;public BookingWizardPage() {&lt;br /&gt;super("booking.pageone","New Booking Entry", null);&lt;br /&gt;errorMessageHandler = new WizardPageErrorHandler();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void createControl(Composite parent) {&lt;br /&gt;final Composite composite = new Composite(parent, SWT.NONE);&lt;br /&gt;composite.setLayout(new GridLayout(2, false));&lt;br /&gt;&lt;br /&gt;strValToolkit = new StringValidationToolkit(DECORATOR_POSITION,&lt;br /&gt;    DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;strValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;intValToolkit = new ValidationToolkit&lt;integer&gt;(new IntegerStringConverter(),&lt;br /&gt;    DECORATOR_POSITION, DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;intValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;dateValToolkit = new ValidationToolkit&lt;date&gt;(new DateStringConverter(),&lt;br /&gt;    DECORATOR_POSITION, DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;dateValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;//TODO: create ValidatingFields&lt;br /&gt;setControl(composite);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/date&gt;&lt;/integer&gt;&lt;/integer&gt;&lt;/date&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The &lt;b&gt;StringValidationToolkit&lt;/b&gt; class we instantiate in &lt;b&gt;line 28&lt;/b&gt; is a &lt;b&gt;ValidationToolkit&lt;/b&gt; that deals specifically with &lt;b&gt;ValidatingField&lt;/b&gt;s that&lt;br /&gt;have normal &lt;b&gt;String&lt;/b&gt; contents. In &lt;b&gt;line 32&lt;/b&gt; we instantiate a typed instance of &lt;b&gt;ValidationToolkit&lt;/b&gt; that will create &lt;b&gt;ValidatingField&lt;/b&gt;s that only&lt;br /&gt;takes &lt;b&gt;Integer&lt;/b&gt;s as input.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We must provide a way that the contents of the fields are converted from a &lt;b&gt;String&lt;/b&gt; to the correct content type. This is done with a set of converter classes&lt;br /&gt;provided by the framework. Custom converters can easily be implemented as well. In &lt;b&gt;lines 32&lt;/b&gt; and &lt;b&gt;36&lt;/b&gt; we specify a &lt;b&gt;IntegerStringConverter&lt;/b&gt; and a &lt;b&gt;DateStringConverter&lt;/b&gt; to convert &lt;b&gt;Integer&lt;/b&gt; and &lt;b&gt;java.util.Date&lt;/b&gt; values respectively.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The framework makes use of the JFace &lt;b&gt;org.eclipse.jface.fieldassist.ControlDecoration&lt;/b&gt; and related classes to indicate whether a field has an error or warning condition, whether it is a required field, and if there is a quick-fix available (by right-clicking on the decorator icon) for the current error or warning condition. The position of these decorator icons relative to the input widgets as well as the margin width between the decorator icon and the widget can be specified when constructing a &lt;b&gt;ValidationToolkit&lt;/b&gt;. All the fields created by this &lt;b&gt;ValidationToolkit&lt;/b&gt; instance will use the same settings for their decorator icons. In &lt;b&gt;lines 9 - 10&lt;/b&gt; we have defined some constants for the decorator position and margins, and we use this for constructing all the &lt;b&gt;ValidationToolkit&lt;/b&gt; instances.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Handling the error messages&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;We also make use of an &lt;b&gt;IFieldErrorMessageHandler&lt;/b&gt; to get feedback from the validation process. The validation framework will call these error handlers when error or warning conditions occur, and allow us to do something with those messages. By default these messages are only displayed in the tooltips of the decorator icons. A&lt;br /&gt;default error handler can be specified for each toolkit instance, or a separate handler can be set for each &lt;b&gt;ValidatingField&lt;/b&gt; if so required.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The inner class &lt;b&gt;WizardPageErrorHandler&lt;/b&gt; implements the &lt;b&gt;IFieldErrorMessageHandler&lt;/b&gt; interface and basically just set the messages on the &lt;b&gt;WizardPage&lt;/b&gt;'s message area.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;//inner class of BookingWizardPage&lt;br /&gt;class WizardPageErrorHandler implements IFieldErrorMessageHandler {&lt;br /&gt;&lt;br /&gt;public void handleErrorMessage(String message, String input) {&lt;br /&gt;setMessage(null, DialogPage.WARNING);&lt;br /&gt;setErrorMessage(message);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void handleWarningMessage(String message, String input) {&lt;br /&gt;setErrorMessage(null);&lt;br /&gt;setMessage(message, DialogPage.WARNING);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void clearMessage() {&lt;br /&gt;setErrorMessage(null);&lt;br /&gt;setMessage(null, DialogPage.WARNING);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The actual error or warning messages are generated by the various &lt;b&gt;IFieldValidator&lt;/b&gt; implementations (we'll get to those), and can easily be customized by implementing custom validators.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Creating a simple ValidatingField&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Of course just having some toolkit instances does not help us much. We need actual input widgets that are being validated. The first step is to update the &lt;i&gt;createControl&lt;/i&gt; method of the wizard-page by adding &lt;b&gt;lines 17 - 20&lt;/b&gt; below.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;public void createControl(Composite parent) {&lt;br /&gt;final Composite composite = new Composite(parent, SWT.NONE);&lt;br /&gt;composite.setLayout(new GridLayout(2, false));&lt;br /&gt;&lt;br /&gt;strValToolkit = new StringValidationToolkit(DECORATOR_POSITION,&lt;br /&gt;    DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;strValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;intValToolkit = new ValidationToolkit&lt;integer&gt;(new IntegerStringConverter(),&lt;br /&gt;    DECORATOR_POSITION, DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;intValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;dateValToolkit = new ValidationToolkit&lt;date&gt;(new DateStringConverter(),&lt;br /&gt;    DECORATOR_POSITION, DECORATOR_MARGIN_WIDTH, true);&lt;br /&gt;dateValToolkit.setDefaultErrorMessageHandler(errorMessageHandler);&lt;br /&gt;&lt;br /&gt;createNameField(composite);&lt;br /&gt;createDateField(composite);&lt;br /&gt;createNumberPersonsField(composite);&lt;br /&gt;createTelephoneNumberField(composite);&lt;br /&gt;&lt;br /&gt;setControl(composite);&lt;br /&gt;}&lt;br /&gt;&lt;/date&gt;&lt;/integer&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Then we can look at creating our first validated input field that makes use of a SWT &lt;b&gt;Text&lt;/b&gt; widget to capture the name of the person doing the booking.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;private void createNameField(Composite composite) {&lt;br /&gt;new Label(composite, SWT.NONE).setText("Booking Name:");&lt;br /&gt;&lt;br /&gt;final ValidatingField&lt;string&gt; nameField = strValToolkit.createTextField(&lt;br /&gt;composite, new IFieldValidator&lt;string&gt;(){&lt;br /&gt;&lt;br /&gt; public String getErrorMessage() {&lt;br /&gt;  return "Name may not be empty.";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getWarningMessage() {&lt;br /&gt;  return "That's a very short name...";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isValid(String contents) {&lt;br /&gt;  return !(contents.length()==0);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;    public boolean warningExist(String contents) {&lt;br /&gt;     return contents.length() &lt; 3;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;   }, true, "");&lt;br /&gt; GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);&lt;br /&gt; gd.widthHint = DEFAULT_WIDTH_HINT;&lt;br /&gt; nameField.getControl().setLayoutData(gd);&lt;br /&gt;}&lt;br /&gt;&lt;/string&gt;&lt;/string&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Since this field works with &lt;b&gt;String&lt;/b&gt; contents, we make use of the &lt;i&gt;strValToolkit&lt;/i&gt; instance to create the field in &lt;b&gt;line 4&lt;/b&gt; above.&lt;br /&gt;We specify the parent composite that the input widget must be added to, the &lt;b&gt;IFieldValidator&lt;/b&gt; that will be used to validate the field contents, whether this is a required field or not (thus whether the required decorator icon must be shown or not) and an initial empty string value for the field. Note that this call will also create a &lt;b&gt;Text&lt;/b&gt; widget to be used for the field, but the API allows that you can create your own &lt;b&gt;Text&lt;/b&gt;, &lt;b&gt;Combo&lt;/b&gt; or &lt;b&gt;CCombo&lt;/b&gt; instance and pass that to the toolkit to use when creating a new &lt;b&gt;ValidatingField&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;An anonymous inner class implementation of &lt;b&gt;IFieldValidator&lt;/b&gt; is specified in &lt;b&gt;lines 5 - 23&lt;/b&gt;. We're doing some very basic validation checks in this example, but&lt;br /&gt;it is easy to implement validators that makes use of other heavy-weight business validation frameworks. Our validator will indicate an error condition if the contents of the field is empty (&lt;b&gt;line 16&lt;/b&gt;), in which case the error message "Name may not be empty." will be displayed (&lt;b&gt;line 8&lt;/b&gt;). This validator will also indicate a&lt;br /&gt;warning condition if the name field contains less than 3 characters (&lt;b&gt;line 20&lt;/b&gt;) with the message "That's a very short name..." (&lt;b&gt;line 12&lt;/b&gt;).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In &lt;b&gt;lines 24 - 26&lt;/b&gt; we set the layout of the input widget on the composite.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Dating an input mask&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Dates have always been a difficult input type to deal with. The easiest way for us developers to deal with them are to use widgets that pop up a calendar from where the user can choose a day, and possibly a time as well. However, this way of dealing with dates are not always a favourite with touch-typing end-users. They prefer some masked field where they only need to fill in the bits of the date that matter. Using the mouse should be restricted as far as possible. Luckily the &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;RCP Toolbox&lt;/a&gt; provides a way of specifying input masks, as well as specific implementations of validators and converters for dealing with Dates.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We want to create a field that only takes dates as input, where the date entered must be of the form &lt;i&gt;yyyy-MM-dd HH:mm&lt;/i&gt; (e.g 2008-07-19 21:00), and fall in the date range starting at the current time and ending at the end of the year 2008.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;private void createDateField(Composite composite) {&lt;br /&gt;new Label(composite, SWT.NONE).setText("Booking Time:");&lt;br /&gt;&lt;br /&gt;final Date endYear = getEndYearDate();&lt;br /&gt;//we create a Date field that takes input of form yyyy-MM-dd HH:mm&lt;br /&gt;//and only allows values from now till the end of the year&lt;br /&gt;final ValidatingField&lt;date&gt; rangedDateField&lt;br /&gt;= dateValToolkit.createTextField(composite,&lt;br /&gt;new RangedDateFieldValidator(&lt;br /&gt;  DateFieldValidator.DATE_TIME_HHMM_DASH,&lt;br /&gt;  dateValToolkit.getStringConverter(),&lt;br /&gt;  new Date(), endYear),&lt;br /&gt;  true,&lt;br /&gt;  new Date());&lt;br /&gt;GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);&lt;br /&gt;gd.widthHint = DEFAULT_WIDTH_HINT;&lt;br /&gt;rangedDateField.getControl().setLayoutData(gd);&lt;br /&gt;}&lt;br /&gt;&lt;/date&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Here we used the &lt;i&gt;dateValToolkit&lt;/i&gt; instance to create the field as the contents of the field must be a &lt;b&gt;java.util.Date&lt;/b&gt;. We specify an instance of &lt;b&gt;RangedDateFieldValidator&lt;/b&gt; (provided by the framework) that makes use of the specified Date input mask pattern &lt;i&gt;DateFieldValidator.DATE_TIME_HHMM_DASH&lt;/i&gt; (&lt;b&gt;line 9&lt;/b&gt;) to validate the contents of the field. Other patterns are available, or custom ones can also be defined. The &lt;b&gt;DateStringConverter&lt;/b&gt; specified when &lt;i&gt;dateValToolkit&lt;/i&gt; was constructed will be used to convert from Dates to Strings and vice versa.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In &lt;b&gt;line 11&lt;/b&gt; we specify the valid date range for the field, from the current date and time to the end of the year, and in &lt;b&gt;line 13&lt;/b&gt; we set the initial&lt;br /&gt;value of the field to the current time.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Providing quick-fixes&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;I found that developers using Eclipse RCP to develop their applications like to make the experience for the end-user as good as possible. So we should not stop at just&lt;br /&gt;validating input; we must also try and help them quickly fix mistakes, where possible. In this example we can do that by specifying a &lt;b&gt;IQuickFixProvider&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;//add at end of createDateField(..) method&lt;br /&gt;//we add a quickfix that will set it to the current date&lt;br /&gt;rangedDateField.setQuickFixProvider(new IQuickFixProvider&lt;date&gt;(){&lt;br /&gt;&lt;br /&gt;public boolean doQuickFix(ValidatingField&lt;date&gt; field) {&lt;br /&gt;field.setContents(new Date());&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getQuickFixMenuText() {&lt;br /&gt;return "Set to current time";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public boolean hasQuickFix(Date contents) {&lt;br /&gt;//would typically first check contents to determine if quickfix&lt;br /&gt;//is possible&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/date&gt;&lt;/date&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The above is a very simple quick-fixer. It always says it has a quick-fix available (&lt;b&gt;line 17&lt;/b&gt;), where a more complex provider will first check the contents of the field to determine if there is a quick-fix. When the user performs the quick-fix, it just sets the contents of the field to the current date and time (&lt;b&gt;line 6&lt;/b&gt;).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;When the validation framework detects there is an error condition on a field, it will see if there is a &lt;b&gt;IQuickFixProvider&lt;/b&gt; available with a quick-fix. If this is the case, it will add the quick-fix option to a context-menu on the decorator icon with the text specified in &lt;b&gt;line 11&lt;/b&gt;. All the user then needs to do is right-click on the decorator icon and select the quick-fix to perform.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Validating Combos&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;A &lt;b&gt;Combo&lt;/b&gt; widget would be just the thing to use for capturing the number of persons for the booking. Our requirements say we must limit the number to a maximum of 10 people (and a minimum of 1 goes without saying). Once again we do not want to force the user to use numerous mouse-clicks or keystrokes to select the number, so we do not make the Combo read-only, and rather decide to add validation to it.&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;private void createNumberPersonsField(Composite composite) {&lt;br /&gt;new Label(composite, SWT.NONE).setText("Number of persons:");&lt;br /&gt;&lt;br /&gt;final ValidatingField&lt;integer&gt; numberPersonsField&lt;br /&gt;= intValToolkit.createComboField(&lt;br /&gt;  composite, new StrictRangedNumberFieldValidator&lt;integer&gt;(1, 10){&lt;br /&gt;   public String getErrorMessage() {&lt;br /&gt;    return "Bookings for groups bigger than 10 not allowed";&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public String getWarningMessage() {&lt;br /&gt;    return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public boolean warningExist(Integer contents) {&lt;br /&gt;    return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;  },&lt;br /&gt;  true,&lt;br /&gt;  2,&lt;br /&gt;  new Integer[]{1,2,3,4,5,6,7,8,9,10});&lt;br /&gt;GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);&lt;br /&gt;gd.widthHint = DEFAULT_WIDTH_HINT;&lt;br /&gt;numberPersonsField.getControl().setLayoutData(gd);&lt;br /&gt;}&lt;br /&gt;&lt;/integer&gt;&lt;/integer&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Here we make use of the &lt;i&gt;intValToolkit.createComboField&lt;/i&gt; method to create a field containing a &lt;b&gt;Combo&lt;/b&gt; widget with contents of type &lt;b&gt;Integer&lt;/b&gt;. We specify&lt;br /&gt;a &lt;b&gt;StrictRangedNumberFieldValidator&lt;/b&gt; (&lt;b&gt;line 6&lt;/b&gt;) to ensure that the entered value only consists of digits and falls in the range 1 to 10. No warning conditions are checked. In &lt;b&gt;line 22&lt;/b&gt; we populate the Combo with a list of Integers from 1 to 10, and in &lt;b&gt;line 21&lt;/b&gt; we select a default value of 2. As easy as counting to 5.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;And don't forget the telephone number&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Freeform telephone number fields are used a lot, but unfortunately end-users can easily make mistakes in such fields. We want to force our user to input the telephone number in a specific form, thus at least preventing the cases where digits are missed. To do this, we make use of the framework's &lt;b&gt;TelephoneNumberValidator&lt;/b&gt;. This validator allows telephone number to be entered in either international format (e.g. +44 (55) 555-5555) or in domestic format (e.g. (055) 555-5555).&lt;/p&gt;&lt;br /&gt;&lt;pre class="java"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;private void createTelephoneNumberField(Composite composite) {&lt;br /&gt;new Label(composite, SWT.NONE).setText("Contact Telephone Nr:");&lt;br /&gt;&lt;br /&gt;final ValidatingField&lt;string&gt; telephoneField&lt;br /&gt;= strValToolkit.createTextField(&lt;br /&gt;  composite,&lt;br /&gt;  new TelephoneNumberValidator(true),&lt;br /&gt;  true,&lt;br /&gt;  "+44 (55) 555-4321");&lt;br /&gt;&lt;br /&gt;GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);&lt;br /&gt;gd.widthHint = DEFAULT_WIDTH_HINT;&lt;br /&gt;telephoneField.getControl().setLayoutData(gd);&lt;br /&gt;}&lt;br /&gt;&lt;/string&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;We are using &lt;i&gt;strValToolkit&lt;/i&gt; to create the field, since the contents will be managed as a String. Then we specify a &lt;b&gt;TelephoneNumberValidator&lt;/b&gt; as the validator&lt;br /&gt;in &lt;b&gt;line 7&lt;/b&gt;, with the &lt;i&gt;true&lt;/i&gt; parameter indicating that we want to use the international format. In &lt;b&gt;line 9&lt;/b&gt; we provide an initial value.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;This article describes a very simple example of how to add validation to SWT widgets using the &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;RCP Toolbox&lt;/a&gt;. In a real-world application the actual business validations to be done might be more complex, but if this validation framework is used, the UI code related to validation would remain as simple as the code in these examples.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This validation framework really made our development much easier, allowing us to concentrate on the business code. It is very easy to extend the framework with custom&lt;br /&gt;validators, converters, quick-fix providers and error handlers that ties into existing business code or other validation code, rules engines etc.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;i&gt;Note that the examples in this article need &lt;a href="http://www.eclipse.org/"&gt;Eclipse RCP&lt;/a&gt; &lt;b&gt;3.3&lt;/b&gt; or &lt;b&gt;3.4&lt;/b&gt; as well as &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;RCP Toolbox&lt;/a&gt; &lt;b&gt;v1.0.1&lt;/b&gt;, created and distributed by&lt;br /&gt;&lt;a href="http://www.richclientgui.com/"&gt;www.richclientgui.com&lt;/a&gt;.&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-2139048021069468427?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/2139048021069468427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=2139048021069468427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2139048021069468427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/2139048021069468427'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2008/07/adding-eclipse-swt-input-validation.html' title='Adding Eclipse SWT input validation the easy way'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-3878107970388110273</id><published>2008-07-03T02:35:00.000-07:00</published><updated>2008-07-03T02:38:46.431-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='RCP'/><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='validation'/><title type='text'>RCP Toolbox 1.0 Released!</title><content type='html'>&lt;p&gt;I've been using Eclipse RCP for a number of years now, since version 2.1. In this time I've found that I needed to provide some customization of certain widgets or add validation to input fields quite a number of times. &lt;/p&gt;   &lt;p&gt;So I thought one day to take these typical custom widgets and validation classes and combine them into a package. I got some other people to help, and we incubated what we decided to call the 'RCP Toolbox' in &lt;a href="http://rcptoolbox.sourceforge.net"&gt;Sourceforge&lt;/a&gt;.&lt;/p&gt;   &lt;p&gt;Then we added more features, including a lightweight Validation framework, Developer's Guide, and of course free technical support and released a commercial version yesterday. &lt;/p&gt;   &lt;p&gt;So I'm very proud to announce the release of &lt;span style="font-weight: bold;"&gt;RCP Toolbox 1.0&lt;/span&gt; on this blog.&lt;br /&gt;Please visit our &lt;a href="http://www.richclientgui.com/detail.php?product_id=1"&gt;product page&lt;/a&gt; for more information on the toolbox.&lt;/p&gt;   &lt;p&gt;And I hope you'll forgive me for this announcement in my blog... but I had to share it with someone :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-3878107970388110273?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/3878107970388110273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=3878107970388110273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/3878107970388110273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/3878107970388110273'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2008/07/rcp-toolbox-10-released.html' title='RCP Toolbox 1.0 Released!'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1872922649370966015.post-8995530997513928930</id><published>2008-05-17T13:18:00.000-07:00</published><updated>2008-05-17T13:42:32.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='java 6'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Best Java environment ever... until...</title><content type='html'>I converted about a year ago. First there was Windows (I knew no better), then there was Linux (happy student years) and then again Windows (the employer's choice). &lt;div&gt;Then a year ago I converted to a Macbook Pro (It helps to have one's own &lt;a href="http://www.richclientgui.com"&gt;company&lt;/a&gt;). This is indeed the nicest machine and OS I've ever done Java development on. I was so happily coding away, using the Eclipse IDE and Leopard's built-in Subversion for version control.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That is, until a project at one of my clients went over to Java 6.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I went to &lt;a href="http://developer.apple.com"&gt;Apple&lt;/a&gt; and downloaded the latest &lt;a href="http://www.apple.com/support/downloads/javaformacosx105update1.html"&gt;Apple 64bit JDK (Java 1.6.0_05)&lt;/a&gt;. This would have worked, but... guess what? The Mac OS X SWT (see &lt;a href="http://www.eclipse.org"&gt;Eclipse&lt;/a&gt;) is not supported by the new Apple Java 6 JDK, as SWT is based on Carbon native code, and the 64bit Java 6 JDK only supports Cocoa... [Anyone with tips on how to run Eclipse RCP apps - including the Eclipse IDE - with the Java 6 VM, please contact me.]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what to I do? For non-SWT code everything is fine. For SWT code: I code blindly on the Mac side of things, check in to svn, fire up Parallels with a Windows VM, get from svn, compile it in the VM's Eclipse and run. Ultimately non-efficient, yes. I do find though that this way of working has dramatically improved my ability to visualise a GUI by looking at the code :-) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the NextStep? Starting to learn the NextSTEP-based Cocoa Framework (what I've seen up to now: Awesome!) so that I can perhaps give a hand with porting SWT on the Mac from Carbon to Cocoa (as Apple does not seem that keen on having Java 6 support Carbon...)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1872922649370966015-8995530997513928930?l=hermanlintvelt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hermanlintvelt.blogspot.com/feeds/8995530997513928930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1872922649370966015&amp;postID=8995530997513928930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/8995530997513928930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1872922649370966015/posts/default/8995530997513928930'/><link rel='alternate' type='text/html' href='http://hermanlintvelt.blogspot.com/2008/05/best-java-environment-ever-until.html' title='Best Java environment ever... until...'/><author><name>Herman Lintvelt</name><uri>http://www.blogger.com/profile/17956758099659763200</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_9tmwCBlMWZM/Sgf18yMkNcI/AAAAAAAAAAM/iMWysbJRdr8/S220/Profile_HK.jpg'/></author><thr:total>0</thr:total></entry></feed>
