<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hexapixel &#187; Programming</title>
	<atom:link href="http://hexapixel.com/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://hexapixel.com</link>
	<description>Programming, Eclipse, SWT and everything inbetween</description>
	<lastBuildDate>Fri, 05 Mar 2010 15:28:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MenuManagers and You</title>
		<link>http://hexapixel.com/2009/05/22/menumanagers-and-you</link>
		<comments>http://hexapixel.com/2009/05/22/menumanagers-and-you#comments</comments>
		<pubDate>Fri, 22 May 2009 10:23:13 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[JFace]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=689</guid>
		<description><![CDATA[If you&#8217;re using Eclipse RCP (or even standalone SWT with JFace) you are most likely using MenuManagers in various places, for popup menus, toolbar menus, etc. You might be happily using them without much of a thought or care of where they end up after they have been shown or how their internal workings actually [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using Eclipse RCP (or even standalone SWT with JFace) you are most likely using MenuManagers in various places, for popup menus, toolbar menus, etc. You might be happily using them without much of a thought or care of where they end up after they have been shown or how their internal workings actually &#8220;work&#8221;. Danger lies down that happy path. </p>
<p>You probably never paid much attention to the disposal of widgets except that &#8220;master widget&#8221; you call <code>dispose()</code> on (usually a shell).. and just because of this, it&#8217;s time to dig into the &#8220;why&#8221;, &#8220;what&#8221; and &#8220;no kidding&#8221; of MenuManagers as there are undoubtedly a few of the &#8220;no kidding&#8221; unless you are already fully familiar with them.</p>
<p><span id="more-689"></span>If you look at the MenuManager API, you&#8217;ll see an often overlooked <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/action/MenuManager.html#dispose()" target="_new">dispose()</a> method. MenuManagers need disposal?! Yep, they sure do. Here&#8217;s a seemingly harmless sample snippet. We create a Shell, a Toolbar, on which we create a MenuManager, and then we dispose the toolbar. You&#8217;d think that the MenuManager would get disposed also wouldn&#8217;t you? It doesn&#8217;t. Where is it? In memory.</p>
<pre>
<pre class="syntax-highlight:java">
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;

public class MenuManagerTest1 {

    public MenuManagerTest1() {
        Display display = new Display();
        Shell shell = new Shell(display, SWT.SHELL_TRIM);
        shell.setLayout(new FillLayout());

        ToolBarManager tbm = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
        tbm.add(new OneAction());
        ToolBar tb = tbm.createControl(shell);

        MenuManager mm = new MenuManager(&quot;Test Menu&quot;);
        mm.add(new OneAction());
        tbm.setContextMenuManager(mm);

        // dispose shell, this will dispose all sub-widgets as well
        shell.dispose();

        // check status of our stuff
        System.out.println(&quot;Toolbar is disposed? - &quot; + tb.isDisposed());
        System.out.println(&quot;Menu is disposed? - &quot; + mm.getMenu().isDisposed());
        System.out.println(&quot;ToolbarManager contains what? &quot; + tbm.getItems());
        System.out.println(&quot;MenuManager contains what? &quot; + mm.getItems());
    }

    class OneAction extends Action {
        public OneAction() {
            super(&quot;Test Action&quot;);
        }

        @Override
        public void run() {
            System.out.println(&quot;Action was run&quot;);
        }
    }

    public static void main(String[] args) {
        new MenuManagerTest1();
    }

}
</pre>
</pre>
<p>The printout when running this will look like;
<pre><font color="green"><b>
Toolbar is disposed? - true
Menu is disposed? - true
ToolbarManager contains what? [Lorg.eclipse.jface.action.IContributionItem;@16fe0f4
MenuManager contains what? [Lorg.eclipse.jface.action.IContributionItem;@19d0a1
</b></font></pre>
<p>Ok, so that's not the most intriguing printout ever, but it's mostly to show that the items are still there. The reason a manager doesn't get disposed should be pretty obvious: It's not a widget, it has no disposable parent (which would also have to be a widget), thus, it exists as long as you let it exist. There is of course a reference to the actual Menu inside the MenuManager, which is disposed as you can see above.</p>
<p>So why aren't MenuManagers auto-disposed in some other fashion, like when the menu is disposed? For good reason. You can create them without a parent widget which means you can keep them around and re-use them like a Factory and because of this, there is no auto-dispose when the menu is hidden. It's actually to make life easier for you even if it sometimes doesn't feel that way.</p>
<h2><b>Disposing MenuManagers</b></h2>
<p>There's two ways you can go about dealing with disposing your MenuManagers. Here's the first one (which might be obvious);</p>
<p>Assume you have a few MenuManagers in your ViewParts or EditParts. If you are creating them inside methods, you will want to refactor them out and create them only once for your class. They should be accessible and re-used throughout the life of the ViewPart and disposed when the ViewPart is disposed. This is very important! If you do not dispose it, it will not be gone, and you will most likely end up with a memory leak (as the above snippet showed). Here's a typical ViewPart dispose() override:</p>
<pre>
<pre class="syntax-highlight:java">
@Override
public void dispose() {
        try {
            if (_toolbarMenu != null) {
                _toolbarMenu.dispose();
                _toolbarMenu = null;
            }

        }
        catch (Exception err) {
            // do something with exception
        }

	    // remember to keep it going!
        super.dispose();
}
</pre>
</pre>
<p>The second option is for the "show once" menus that you may have. How do you dispose those? Ideally the same as #1 but if you really have to dispose them differently, the easiest way to do it is to "auto dispose" them once the user has seen the menu and closed it or selected something from it. You will most likely create your <code>Menu</code> object from a call to <code>menuManager.createContextMenu(...)</code>, so after this when you have the Menu object available, you do something like this;</p>
<pre>
<pre class="syntax-highlight:java">
final MenuManager mm = new MenuManager(&quot;Menu&quot;);

// ... various manager-related code here

// create menu object on widget
Menu menu = mm.createContextMenu(parentWidget);

// add a listener that disposes the MenuManager once user has seen the menu
menu.addMenuListener(new MenuListener() {

	 @Override
	 public void menuHidden(MenuEvent e) {
	     // dispose asynchronously or it&#039;ll dispose too fast and menu item clicked won&#039;t be run
	     Display.getDefault().asyncExec(new Runnable() {

		 @Override
		 public void run() {
		     mm.dispose();
		 }

	     });
	 }

	 @Override
	 public void menuShown(MenuEvent e) {
	 }

});
</pre>
</pre>
<p>It's not the prettiest solution, but it works. Ok, so the disposal is covered now, no more leaks. Yay for us!</p>
<p>There is one more thing to bring up that you may/may not encounter, but if you do, it would probably be a head-scratcher. </p>
<h2><b>Dynamic Menu Items</b></h2>
<p>Here's a scenario that happened to me and at first seemed to be a bug:</p>
<p>We have a lot of tables in our application. We also have a section where users can create their own custom filters. These filters show up in our menus when you right click a table or open a menu on the toolbar. When a filter is in use, the corresponding menu item for that filter is checked. Each filter is wrapped in an IAction that overrides <code>equals()</code> and <code>hashCode()</code> that both check to see if the wrapped Filter object is the same. Thus, any action using the same filter object will return true in the <code>equals()</code> check. </p>
<p>We have an <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/action/IMenuListener.html" target="_new">IMenuListener</a> on the menu, so whenever the user opens the menu, just as it's being shown, we remove all old menu items in the "Filters" menu and re-create them (as filters may have changed by the user without our knowledge). We then "check" (checkbox) them according to what filters are active in the table. All this works fine, and here's where the issue arose;</p>
<p>We also have a MenuManager on our toolbar (ToolbarManager) associated with the table. This toolbar menu shows the exact same filter menu when popped up, through the same methods. The issue is easiest described through this chain of events...</p>
<ol>
<li>User opens right click filter menu, selects a filter, item is checked, filter is applied to table.</li>
<li>User looks at toolbar menu, sees filter checked (do note this is the first time the toolbar menu was opened). Closes menu without selecting anything.</li>
<li>User opens right click filter menu again, selects same filter as before (the now checked one). Item is no longer checked, filter is removed from table.</li>
<li>User opens toolbar menu again, <b>sees the recently cleared filter still checked</b>(!). At this point it will always stay checked. Had we looked at the menu when stuff was unchecked, it would forever be unchecked.</li>
</ol>
<p>I debugged this for a long time until I to my horror realized that despite me calling <code>removeAll()</code> and re-creating all MenuManager items in the "Filters" menu on each popup, internally, in the Menu widget itself, the <code>removeAll()</code> on the MenuManager removed nothing on the Menu widget. All MenuItems were still there! Hmm, what was going on? what was I missing? Why didn't <code>removeAll()</code> remove all MenuItems as well? </p>
<p>I debugged some more and noticed some code inside the MenuManager source code that looks like this:</p>
<pre>
<pre class="syntax-highlight:java">
for (int i = 0; i &lt; mi.length; i++) {
    Object data = mi[i].getData();

    if (data == null || !clean.contains(data)) {
	mi[i].dispose();
    } else if (data instanceof IContributionItem
	    &amp;amp;&amp;amp; ((IContributionItem) data).isDynamic()
	    &amp;amp;&amp;amp; ((IContributionItem) data).isDirty()) {
	mi[i].dispose();
    }
}
</pre>
</pre>
<p>This loop first of all removes all items that are not the same as before (that are in the <code>clean</code> array), that's good. But as I checked what got disposed, our filter items were never removed... as they are the same as before! Aha! So the second part of the if-statement checks to see if the item is Dirty or Dynamic. This was the first I had heard of Dynamic menu items and it felt like I had read the API through and through many times. The API for <code>isDynamic()</code> says:</p>
<p><i>Returns whether this contribution item is dynamic. A dynamic contribution item contributes items conditionally, dependent on some internal state.</i></p>
<p>Cryptic to say the least, and easily overlooked as it's very non-descriptive, but with the above looping code and how we deal with these special actions - it kind of fits. We depend on the items having checkmarks which depend on an internal state (which is; if the table filter is active or not). The MenuManager can't figure that out by itself of course, so we need to help it. The solution to this problem is obvious at this point. If <code>isDynamic()</code> returns true it will be disposed for us, so we need to implement that and return <code>true</code>.</p>
<p>In our code more or less everything is an IAction, for our FilterAction we create a DynamicFilterAction class that extends <code>ActionContributionItem</code> and then we override <code>isDynamic()</code> and return <code>true</code>. </p>
<p>This ensures that there is no "old" items in the menu (as now our Dynamic menu items get disposed) when we create the new one, and as such, the "checkbox issue" goes away and everything works as intended. The final code looks something like this;</p>
<pre>
<pre class="syntax-highlight:java">
class DynamicFilterAction extends ActionContributionItem {

        private FilterAction _action;

        public DynamicFilterAction(DataFilter df) {
            super(new FilterAction(df));
            _action = (FilterAction)super.getAction();
        }

        public void setChecked(boolean checked) {
            _action.setChecked(checked);
        }

        @Override
        public boolean isDynamic() {
            return true;
        }
}
</pre>
</pre>
<h2><b>Final Words</b></h2>
<p>Hopefully this gives you a better insight into the rather simple but tricky world of MenuManagers and how they work. Taking good care of them will ensure that you at least don't have to worry about them sticking around in memory or doing things you didn't expect.</p>
<p>Happy menu managing!</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/05/22/menumanagers-and-you/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java Source Helper 0.2.4</title>
		<link>http://hexapixel.com/2009/05/09/javasourcehelper-024</link>
		<comments>http://hexapixel.com/2009/05/09/javasourcehelper-024#comments</comments>
		<pubDate>Sat, 09 May 2009 15:26:16 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[sourcehelper]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=677</guid>
		<description><![CDATA[I&#8217;ve released a new version of the JavaSourceHelper, 0.2.4, which fixes the following: Brackets inside comments are no longer mistaken for “matching” brackets If the starting bracket and end bracket were not in the same location, the connecting line would draw funny, now it draws a bend Preferences page moved to under Java then “Java [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released a new version of the JavaSourceHelper, 0.2.4, which fixes the following:</p>
<ol>
<li>Brackets inside comments are no longer mistaken for “matching” brackets</li>
<li>If the starting bracket and end bracket were not in the same location, the connecting line would draw funny, now it draws a bend</li>
<li>Preferences page moved to under Java then “Java Editor”. Search for helper if you can’t find it in the Preferences dialog.</li>
</ol>
<p>Here&#8217;s a picture of the &#8220;fixed&#8221; line drawing:</p>
<p><img src="http://hexapixel.com/wp-content/uploads/2009/05/improved_line.gif" alt="Improved Line Drawing" title="" width="604" height="130" /></p>
<p>You can update via the update site or download and install/update manually. For more info go to <a href="/projects/sourcehelper">the java source helper page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/05/09/javasourcehelper-024/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Maven Version Clash Detection (and Software)</title>
		<link>http://hexapixel.com/2009/03/17/maven-and-dependency-version-clash-detection</link>
		<comments>http://hexapixel.com/2009/03/17/maven-and-dependency-version-clash-detection#comments</comments>
		<pubDate>Tue, 17 Mar 2009 17:26:46 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=603</guid>
		<description><![CDATA[Maven is a great tool for building Java projects, there&#8217;s no doubt about that. Unfortunately there is one great feature still lacking of Maven which is important when you use third party dependencies, namely detecting when your components use dependencies of different versions without your knowledge. What does that mean? It&#8217;s probably easier to explain [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://maven.apache.org/" target="_new">Maven</a> is a great tool for building Java projects, there&#8217;s no doubt about that. Unfortunately there is one great feature still lacking of Maven which is important when you use third party dependencies, namely detecting when your components use dependencies of different versions without your knowledge. </p>
<p>What does that mean? It&#8217;s probably easier to explain by example. Imagine you have a project that has two dependencies (can be your own created jars or third party, or anything Maven-buildable really). Your first dependency uses Log4J v1.0. Your second dependency uses Log4J v1.1.  When you compile this project Maven will by default use the &#8220;nearest wins&#8221; strategy, meaning it might pick Log4J v1.0 or Log4J v1.1, whichever is nearer in the <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html" target="_new">transitive hull of dependencies</a>. What you probably wanted however, was for the compilation to tell you that you have two &#8220;modules&#8221; depending on the same library, but different versions of that library. Log4J is perhaps not the best example, but imagine that the dependency in question is a mission-critical dependency, and that any version discrepancy may cause catastrophic failures that can be very hard to track down via debugging.</p>
<p>To solve this I wrote a Maven plugin nearly a year ago that we are now using for every Maven-built project in our company. It&#8217;s a simple plugin that does the complex task of detecting all version clashes (even deeply nested ones) and will report them back to you either as warnings or errors (or ignore them). This project was submitted to the Maven team a while back but has not been integrated as a default Maven plugin yet, so it will now become a downloadable Software Project on Hexapixel until it hopefully becomes a standard module. </p>
<p><span id="more-603"></span></p>
<p>So how do you use it? Here&#8217;s a brief explanation and some examples of usage. If you&#8217;d rather skip to the plugin &#8220;homepage&#8221;, please follow <a href="/software/maven-version-clash-plugin">this link</a>.</p>
<h2><strong>Usage / Configuration</strong></h2>
<p>You can either run the clash-detector manually from the command line, or (the best option) is to add it to your POM (ideally your parent POM that all your projects use, you do have one right?) so that it is run automatically whenever you do builds.</p>
<p>There are only two options you can configure, one is the level of warning the plugin should do. By default the level is <code>FAIL</code>, meaning your build will fail if the plugin detects any clashes. The level can be changed either on the command line by supplying the parameter <code>-Dhalt=</code> where the right hand of the equals sign is one of <code>FAIL, WARN or DEBUG</code>. For the POM the same parameter is configured by supplying the same keyword inside a <code>&lt;halt /&gt;</code> tag such as: <code>&lt;halt&gt;WARN&lt;/halt&gt;</code></p>
<p>The second parameter is the level of detection the plugin should do. There are two modes, <code>SHALLOW and DEEP</code>. By default the level is <code>DEEP</code> where clash detection is not limited to the immediate level of the dependency, but also deeply nested dependencies. Shallow detection is only one level down and will not detect deeply nested dependency clashes. This is for example good for when you only care about clashes of your own jars (although I would strongly advice never using it unless really necessary).</p>
<p>Here are two snippets showing how to run the clash detector from the command line and how to configure it inside your POM.</p>
<p><b><strong>Command Line</strong></b></p>
<p>To invoke it from the command line you simply run it like this: </p>
<pre>
<pre class="syntax-highlight:xml">
mvn breakonversionclash:clash-detection -Dhalt=FAIL -Ddepth=SHALLOW
</pre>
</pre>
<p><b>In your POM</b></p>
<pre>
<pre class="syntax-highlight:xml">
&lt;build&gt;
	&lt;plugins&gt;
		&lt;plugin&gt;
			&lt;groupId&gt;com.hexapixel.maven.plugins&lt;/groupId&gt;
			&lt;artifactId&gt;
				maven-breakonversionclash-plugin
			&lt;/artifactId&gt;
			&lt;version&gt;1.0.1&lt;/version&gt;
			&lt;executions&gt;
				&lt;execution&gt;
					&lt;configuration&gt;
						&lt;!-- Options: FAIL, WARN, DEBUG (default is FAIL) --&gt;
						&lt;halt&gt;WARN&lt;/halt&gt;
						&lt;!-- Options: SHALLOW, DEEP (default is DEEP) --&gt;
						&lt;depth&gt;DEEP&lt;/depth&gt;
					&lt;/configuration&gt;
					&lt;phase&gt;compile&lt;/phase&gt;
					&lt;goals&gt;
						&lt;goal&gt;clash-detection&lt;/goal&gt;
					&lt;/goals&gt;
				&lt;/execution&gt;
			&lt;/executions&gt;
		&lt;/plugin&gt;
	&lt;/plugins&gt;
&lt;/build&gt;
</pre>
</pre>
<h2><strong>Plugin in Action</strong></h2>
<p>Here is a typical output the plugin will produce:</p>
<pre>
<pre class="syntax-highlight:xml">
 [INFO] [breakonversionclash:clash-detection {execution: default}]
 [INFO] Checking for dependency version clashes...
 [INFO] Halt mode is: &#039;warn&#039;. Depth mode is: &#039;deep&#039;.
 [WARNING] ------------------------------------------------------------------------
 [WARNING] Dependency version clash on &#039;commons-logging&#039; [1.0.4, 1.1.1]
 [WARNING] ------------------------------------------------------------------------
 [WARNING] Clash 1: commons-logging:commons-logging:1.0.4
 [WARNING] Clash 2: commons-logging:commons-logging:1.1.1
 [WARNING]
 [WARNING] Artifacts using different versions of &#039;commons-logging:commons-logging&#039;:
 [WARNING] - org.hibernate:hibernate:jar:3.2.6.ga
 [WARNING] - com.our.project:plugin-domain:jar:1.0.0.0-SNAPSHOT
 [WARNING]
 [WARNING] Dependency trail for &#039;commons-logging:commons-logging:1.0.4&#039;
 [WARNING] - Node 1: com.our.project:plugin-testdata:pom:1.0.0.0-SNAPSHOT
 [WARNING] - Node 2: com.our.project:plugin-testdata-source:zip:small-datasets:1.0.0.0-SNAPSHOT
 [WARNING] - Node 3: com.our.project:plugin-testdata-generator:jar:1.0.0.0-SNAPSHOT
 [WARNING] - Node 4: com.our.project:plugin-domain:jar:1.0.0.0-SNAPSHOT
 [WARNING] - Node 5: org.hibernate:hibernate:jar:3.2.6.ga
 [WARNING]
 [WARNING] Dependency trail for &#039;commons-logging:commons-logging:1.1.1&#039;
 [WARNING] - Node 1: com.our.project:plugin-testdata:pom:1.0.0.0-SNAPSHOT
 [WARNING] - Node 2: com.our.project:plugin-testdata-source:zip:small-datasets:1.0.0.0-SNAPSHOT
 [WARNING] - Node 3: com.our.project:plugin-testdata-generator:jar:1.0.0.0-SNAPSHOT
 [WARNING] - Node 4: com.our.project:plugin-domain:jar:1.0.0.0-SNAPSHOT
 [WARNING] Found 1 dependency version clash
</pre>
</pre>
<p>Let&#8217;s go over this even though it might be mostly self explanatory. </p>
<p>We have configured the plugin to only warn us when there is a clash, and to do a &#8220;deep&#8221; check, meaning it will not only check immediate dependencies, but also dependencies of dependencies.</p>
<p>It tells us that we have a clash on the usage of &#8216;commons-logging&#8217; and that the two clashing versions are version 1.0.4 and version 1.1.1 of commons-logging.</p>
<p>Then it tells us what jars are using commons-logging, in this case it&#8217;s our dependency on Hibernate and our own plugin-domain project. </p>
<p>It then shows us the dependency &#8220;trail&#8221; for each clash, meaning, it shows what depends on what all the way to the actual dependency of &#8216;commons-logging&#8217;, so that you can easily pinpoint what jars need adjusting so that the clash goes away.</p>
<h2><strong>Download / More Info</strong></h2>
<p>For downloads (binary and source) and more info, please go to the <a href="/software/maven-version-clash-plugin">Version Clash Plugin Page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/03/17/maven-and-dependency-version-clash-detection/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Office UI Licensing and The Ribbon Widget</title>
		<link>http://hexapixel.com/2009/03/02/office-ui-licensing-and-the-ribbon-widget</link>
		<comments>http://hexapixel.com/2009/03/02/office-ui-licensing-and-the-ribbon-widget#comments</comments>
		<pubDate>Mon, 02 Mar 2009 18:49:33 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=578</guid>
		<description><![CDATA[This will not be a long post, but I want to point this out as it may be important. I know some are using the Ribbon Widget in their applications despite the &#8220;Alpha&#8221; state that it is in. This is of course great, but I want to make sure people are aware that Microsoft are [...]]]></description>
			<content:encoded><![CDATA[<p>This will not be a long post, but I want to point this out as it may be important. I know some are using the Ribbon Widget in their applications despite the &#8220;Alpha&#8221; state that it is in. This is of course great, but I want to make sure people are aware that Microsoft are quite proud of their Ribbon (which I think they should be), and as such, they want to know about any application that uses a &#8220;third party&#8221; Ribbon.</p>
<p>What does this mean for you, the user? Not a whole lot, except that Microsoft wants to know that you are using a &#8220;ribbon look-a-like&#8221; widget commercially and they want you to get a license. They have a site set up where you can license the Office UI (which includes the Ribbon), so if you must, you probably should read through it and see how it applies to you. I believe it&#8217;s free, but I haven&#8217;t taken deep look at it yet. The link to this is <a href="http://msdn.microsoft.com/en-us/office/aa973809.aspx" target="_new">http://msdn.microsoft.com/en-us/office/aa973809.aspx</a>.</p>
<p>And another interesting Ribbon related link is something <a href="http://tom-eclipse-dev.blogspot.com/" target="_new">Tom Schindl</a> just sent me, which is a Bugzilla entry for a request to add the Ribbon API to SWT. You can find that here: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=90145" target="_new">https://bugs.eclipse.org/bugs/show_bug.cgi?id=90145</a>. I think it would be fantastic as then it would be native and not custom drawn like the current Ribbon.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/03/02/office-ui-licensing-and-the-ribbon-widget/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java Source Helper 0.2.3</title>
		<link>http://hexapixel.com/2009/02/12/java-source-helper-022</link>
		<comments>http://hexapixel.com/2009/02/12/java-source-helper-022#comments</comments>
		<pubDate>Thu, 12 Feb 2009 21:39:06 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=568</guid>
		<description><![CDATA[*Post updated to reflect bug-fix and version update to 0.2.3. Update site should also work now* A new version of the Java Source Helper is out. This version is almost a rewrite of the entire code as it now uses the Java AST tree for parsing code. This should make it much more &#8220;happy&#8221; with [...]]]></description>
			<content:encoded><![CDATA[<p>*Post updated to reflect bug-fix and version update to 0.2.3. Update site should also work now*</p>
<p>A new version of the Java Source Helper is out. This version is almost a rewrite of the entire code as it now uses the Java AST tree for parsing code. This should make it much more &#8220;happy&#8221; with custom formatted code. The popup will also show the parent-scope history to give you an even better idea of where you are in the code. </p>
<p>There are quite a bunch of new features, and I tried to include all requests I&#8217;ve gotten so far (although some may not have made it in yet). In any case, the details page contains full info including new screenshots, new download links, etc. <a href="/projects/sourcehelper">Go check it out!</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/02/12/java-source-helper-022/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RCP Workspaces</title>
		<link>http://hexapixel.com/2009/01/12/rcp-workspaces</link>
		<comments>http://hexapixel.com/2009/01/12/rcp-workspaces#comments</comments>
		<pubDate>Mon, 12 Jan 2009 20:37:42 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[JFace]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=483</guid>
		<description><![CDATA[An &#8220;Eclipse workspace&#8221; is basically a directory where all your metadata preference files are stored (Eclipse specific files, there&#8217;s a lot of them). It&#8217;s also where your projects are stored, your source files, jars, and so on. It&#8217;s useful to have all of this one one place, and Eclipse itself requires it or your workspace [...]]]></description>
			<content:encoded><![CDATA[<p>An &#8220;Eclipse workspace&#8221; is basically a directory where all your metadata preference files are stored (Eclipse specific files, there&#8217;s a lot of them). It&#8217;s also where your projects are stored, your source files, jars, and so on. It&#8217;s useful to have all of this one one place, and Eclipse itself requires it or your workspace probably won&#8217;t load. As it&#8217;s such a useful feature, I know a lot of people have tried to implement the existing &#8220;Switch Workspace&#8221; and the rest of the &#8220;Workspace&#8221; logic into their RCP applications, but I have yet to see many successes. The issue is that it&#8217;s most likely a feature you will want to customize (and in some aspects, you have to, as the &#8220;Workspace&#8221; implementation in Eclipse is not that open), and that&#8217;s where it gets tricky and possibly messy.</p>
<p>In our case, we wanted the normal Eclipse workspace logic so that users could create multiple &#8220;RCP Workspaces&#8221; and load whichever they wanted at startup, but we also wanted all of our custom RCP application specific data in the same directory (along with any other files we felt like creating), and we wanted to customize the dialog where the user picks a workspace. In the end, as you have probably guessed by now, we used nearly none of the default Eclipse workspace implementation, but managed to get RCP to believe that we were, and we got all the features we required in there as well.</p>
<p>This article will explain how we went about doing this, and will show you (with full source code of course) how you can implement exactly the same thing. And it&#8217;s much easier than it may sound.</p>
<p><span id="more-483"></span></p>
<h2><strong>The Magic Parameter</strong></h2>
<p>Everything starts with one little command line parameter that tells Eclipse we will be in charge of specifying where the workspace goes. Obviously we need to do this very early in the application or else by the time we have a UI, Eclipse has no place to put preferences. And if we do it too late, Eclipse will exit with an exception saying that it has no workspace. The &#8220;Program Argument&#8221; that makes it possible for us to define a workspace at runtime looks like this: <code>-data @noDefault</code>.</p>
<p>If you look at your &#8220;Run Configurations&#8221; in Eclipse (&#8220;Run&#8221; menu, then &#8220;Run Configurations&#8230;&#8221;) and click the &#8220;Arguments&#8221; tab, you will probably see a few cryptic entries that Eclipse has created for you, they look like this: <code>-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl}</code>. By appending our @noDefault argument, we end up with this: <code>-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -data @noDefault</code>.</p>
<p>Here is a screenshot of how it would look when appended:<br />
<img title="Arguments Tab" src="http://hexapixel.com/wp-content/uploads/2009/01/args_tab.gif" alt="Arguments Tab" width="522" height="131" /></p>
<p>So what does that parameter do? It simply tells Eclipse not to use any default workspace location (or &#8220;OSGI instance area&#8221; as it&#8217;s called in the API) when it starts up and expects us to provide it instead. Here&#8217;s an API link to the document explaining the different <a href="http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html" target="_new">Eclipse runtime options</a> you can set (including the ones mentioned here).</p>
<h4><strong>Telling Eclipse The Location Manually</strong></h4>
<p>So, where and how do we tell Eclipse that we have a &#8220;workspace home&#8221; that we want it to use? As I mentioned before, we need to do it early. That means we need to do it in <code>Application.java</code> and more specifically in the <code>public Object start(IApplicationContext context) throws Exception {</code> method. By default this method will mostly be empty except for some Eclipse specific code (undoubtedly generated by Eclipse when you created the RCP project), but we&#8217;ll soon change that. Eclipse will expect us to set the necessary location by modifying the &#8220;InstanceLocation&#8221; on the Platform. We can get the <code>Location</code> by doing a one-line call like this: <code>Location instanceLoc = Platform.getInstanceLocation();</code>. Assuming we already have a specific workspace location in mind, we could do the following:</p>
<pre>
<pre class="syntax-highlight:java">
try {
	// fetch the Location that we will be modifying
	Location instanceLoc = Platform.getInstanceLocation();

	// set location to c:\temp
	instanceLoc.set(new URL(&quot;file&quot;, null, &quot;c:\\temp&quot;), false);
}
catch (Exception err) {
	...
}
</pre>
</pre>
<p>When we create the URL we tell it that the protocol to use is a file. We also tell it that the host is null and that the file in question is <code>c:\temp</code> (which is actually a directory of course). The last <code>false</code> that we pass to the set method is whether we want to lock the workspace location (which we don&#8217;t).</p>
<p>We have now satisfied Eclipse&#8217;s needs for custom-defining a workspace, and when you start your product or RCP application, you should see that Eclipse has created a <code>.metadata</code> directory underneath it. But as we hardcoded the path to <code>c:\temp</code>, this doesn&#8217;t let us &#8220;customize&#8221; it much does it? What about &#8220;Switch Workspace&#8221; functionality and asking the user what workspace they would like to pick? (or create)</p>
<h2><strong>Asking The User</strong></h2>
<p>In our case, we ask users at startup what workspace we should use (Just like Eclipse does). We do various checks to see if the directory they pick is already a workspace, if it&#8217;s writable/readable, and so on. If everything is OK, we return the selected directory to the previous code exmple and put it where we used <code>c:\temp</code> before.</p>
<p>To make it easy, you could re-use code from the &#8220;Select workspace dialog&#8221; from Eclipse, but we want ours custom, so I&#8217;ll explain how that&#8217;s done. </p>
<p>Let&#8217;s create a class called <code>PickWorkspaceDialog</code>, as we&#8217;ll re-use this for the Switch Workspace action later, we&#8217;ll make it with a constructor that takes a boolean that defines whether it&#8217;s the normal &#8220;startup pick workspace&#8221; dialog or if it&#8217;s the &#8220;switch workspace&#8221; dialog. As Eclipse already has a pretty nice dialog that we can re-use that lets us put an image and a message at the top, we&#8217;ll be extending <code>TitleAreaDialog</code>.</p>
<p>While we&#8217;re at it, lets create features for cloning a workspace and a combo that remembers our last selected ones as well.</p>
<p>As it&#8217;s a lot of code to paste into an article &#8211; and I think a lot of it is straight forward &#8211; I will simply link to the entire java class and show some selective snippets below. For starters, this class was created using layouts with the <a href="/files/layout.jar" target="_new">LatticeLayout</a> layout manager (Update: Site is down, old lik was <a href="http://www.quirk.biz/quirkdownloads/index.html" target="_new">here</a>, I&#8217;ve changed link to the direct jar download which contains javadoc and sources as well), so if you don&#8217;t want to re-code those sections, go grab it. (This is a simpler <a href="http://www.miglayout.com" target="_new">MigLayout</a> layout manager) similar to Swing&#8217;s TableLayout. Should you not wish to use either, it should be easy to change the layouts to anything you want (GridLayout for example).</p>
<p>You can download the Java file <a href="/files/posts/PickWorkspaceDialog.java">here</a> (and at the bottom of the article). I suggest you browse through it quickly before we continue as it will make it much easier to follow. Do note that this class has been optimized to &#8220;fit in one class&#8221;, as normally some of the methods found in there would undoubtedly be split up into other places. But for the making this article it was combined into one file.</p>
<h4><strong>Using Preferences</strong></h4>
<p>Normally in a RCP application we would be using an <code>IPreferenceStore</code> to save/load our preferences. But as we need to save the location of what workspace we used last &#8211; before we have access our preference store (which is saved in our not-yet-selected workspace location), we need to save/load from somewhere else. The most logical solution is to use the <a href="http://java.sun.com/j2se/1.4.2/docs/guide/lang/preferences.html" target="_new">java Preferences API</a>. By defining a preference location along the lines of;</p>
<pre>
<pre class="syntax-highlight:java">
// create/get our preferences location based on the class
private static Preferences _preferences = Preferences.userNodeForPackage(PickWorkspaceDialog.class);

// lets define the keys we will be saving
private static final String _KeyWorkspaceRootDir   = &quot;wsRootDir&quot;;
private static final String _KeyRememberWorkspace  = &quot;wsRemember&quot;;
private static final String _KeyLastUsedWorkspaces = &quot;wsLastUsedWorkspaces&quot;;
</pre>
</pre>
<p>we can now save/load those preferences as early or late as we want. Do note that any user launching the application on the same computer will be seeing the same saved preferences, so if you need a more secure or private solution this may not be ideal for you. But for 99% of us this is fine. If you do not know how the Java Preferences API works, take a quick look at the <a href="http://java.sun.com/j2se/1.4.2/docs/guide/lang/preferences.html" target="_new">API</a> or the <a href="/files/posts/PickWorkspaceDialog.java">PickWorkspaceDialog.java</a> file.</p>
<h4><strong>Identifying Our Workspace</strong></h4>
<p>When a user selects a directory, we want to check if that directory is a &#8220;Our Application&#8221; workspace directory or some other plain directory. We do this by creating an empty file when the workspace is created, so that later, if they select an existing directory, we can say if it&#8217;s a valid &#8220;Our Application&#8221; workspace directory or not. In the <code>PickWorkspaceDialog.java</code> class you will see a method named <code>checkWorkspaceDirectory</code> that deals with both checking if a directory already exists or not (to ask if the user wants to create a new workspace there), and it also deals with checking any existing directory to ensure it&#8217;s a workspace directory for our application. The filename is defined at the top of the class, just look for <code>public static final String  WS_IDENTIFIER = ".our_rcp_workspace";</code></p>
<p>You will also see code that checks to ensure the user doesn&#8217;t select a subdirectory of an existing workspace directory, as that could cause an infinite recursive directory-creating loop, which is obviously bad.</p>
<p>Running the code from within RCP will give you a dialog that looks like this (assuming you gave it a nice image to display &#8211; the wizard image used in the screenshot is part of the Eclipse platform, so you can find most of them inside the eclipse jars):</p>
<p><img title="Select Workspace Dialog" src="http://hexapixel.com/wp-content/uploads/2009/01/sel_workspace.gif" alt="Select Workspace Dialog" width="457" height="244" /></p>
<p>As we need to hook it up to actual code, showing the screenshot before we do so makes it easier when I mention things as the &#8220;remember&#8221; checkbox.</p>
<h4><strong>Hooking It Up</strong></h4>
<p>Back in <code>Application.java</code> we now want to change our previous code to use the dialog to ask the user for a workspace. We also need to check if the user selected the &#8220;remember&#8221; checkbox as then we don&#8217;t show the dialog at all (unless the previously selected workspace directory can&#8217;t be found). We also want to check that the old workspace directory is still OK in terms of reading/writing etc. All in all, we want something like this (excuse the formatting, the sourcecode formatter doesn&#8217;t like large deeply nested blocks):</p>
<pre>
<pre class="syntax-highlight:java">
public Object start(IApplicationContext context) throws Exception {
	try {
		// the old Eclipse generated code
		Display display = PlatformUI.createDisplay();
		// and so on..

		// get what the user last said about remembering the workspace location
		boolean remember = PickWorkspaceDialog.isRememberWorkspace();

		// get the last used workspace location
		String lastUsedWs = PickWorkspaceDialog.getLastSetWorkspaceDirectory();

		// if we have a &quot;remember&quot; but no last used workspace, it&#039;s not much to remember
		if (remember &amp;&amp; (lastUsedWs == null || lastUsedWs.length() == 0)) {
		    remember = false;
		}

		// check to ensure the workspace location is still OK
		if (remember) {
		    // if there&#039;s any problem whatsoever with the workspace, force a dialog which in its turn will tell them what&#039;s bad
		    String ret = PickWorkspaceDialog.checkWorkspaceDirectory(Display.getDefault().getActiveShell(), lastUsedWs, false, false);
		    if (ret != null) {
			remember = false;
		    }

		}

		// if we don&#039;t remember the workspace, show the dialog
		if (!remember) {
		    PickWorkspaceDialog pwd = new PickWorkspaceDialog(false);
		    int pick = pwd.open();

		    // if the user cancelled, we can&#039;t do anything as we need a workspace, so in this case, we tell them and exit
		    if (pick == Window.CANCEL) {
			if (pwd.getSelectedWorkspaceLocation()  == null) {
			    MessageDialog.openError(display.getActiveShell(), &quot;Error&quot;,
				    &quot;The application can not start without a workspace root and will now exit.&quot;);
			    try {
				PlatformUI.getWorkbench().close();
			    } catch (Exception err) {

			    }
			    System.exit(0);
			    return IApplication.EXIT_OK;
			}
		    }
		    else {
			// tell Eclipse what the selected location was and continue
			instanceLoc.set(new URL(&quot;file&quot;, null, pwd.getSelectedWorkspaceLocation()), false);
		    }
		}
		else {
		    // set the last used location and continue
		    instanceLoc.set(new URL(&quot;file&quot;, null, lastUsedWs), false);
		}	

		// this is the normal default code from here on out
		int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
		if (returnCode == PlatformUI.RETURN_RESTART) { return IApplication.EXIT_RESTART; }
		return IApplication.EXIT_OK;

	}
	catch (Exception err) {
		...
	}
	finally {
	    display.dispose();
	}
}
</pre>
</pre>
<p>And that&#8217;s it. We now have a fully working and modifiable &#8220;Select Workspace&#8221; dialog that tells Eclipse where to put the metadata and we can modify any of it to our hearts content. With that all out of the way, the only thing remaining is the &#8220;Switch Workspace&#8221; action.</p>
<h2><strong>Switch Workspace</strong></h2>
<p>Eclipse has a built-in Switch Workspace action that you could access from the <code>ActionFactory</code>, but as we custom implemented our workspace picker, this wouldn&#8217;t help us much. Our dialog is already set up to handle a workspace switch (pretty much all it does is show a different message after all).</p>
<p>So, lets create an Action that will be our Switch Workspace action. It will be surprisingly short, and look like this:</p>
<pre>
<pre class="syntax-highlight:java">
public class ActionSwitchWorkspace extends Action {

    private Image _titleImage;

    public ActionSwitchWorkspace(Image titleImage) {
        super(&quot;Switch Workspace&quot;);
        _titleImage = titleImage;
    }

    @Override
    public void run() {
        PickWorkspaceDialog pwd = new PickWorkspaceDialog(true, _titleImage);
        int pick = pwd.open();
        if (pick == Dialog.CANCEL)
            return;

        MessageDialog.openInformation(Display.getDefault().getActiveShell(), &quot;Switch Workspace&quot;, &quot;The client will now restart with the new workspace&quot;);

        // restart client
        PlatformUI.getWorkbench().restart();
    }
}
</pre>
</pre>
<p>As all necessary variables and workspace locations are handled in the <code>PickWorkspaceDialog</code> class we don&#8217;t need to do anything else than tell the picked that it is now a &#8220;Switch Workspace&#8221; dialog, and then restart the RCP application if the user pressed &#8220;OK&#8221;.</p>
<p>Ideally we&#8217;d add this action in our <code>ActionBarAdvisor</code> class (default name is <code>ApplicationActionBarAdvisor</code>) under the File menu somewhere.</p>
<p>The result when run will look like this:</p>
<p><img title="Switch Workspace Dialog" src="http://hexapixel.com/wp-content/uploads/2009/01/sw_workspace.gif" alt="Switch Workspace Dialog" width="457" height="244" /></p>
<h2><strong>That&#8217;s It</strong></h2>
<p>With the code mentioned in this article you now have full &#8220;workspace&#8221; functionality for your Eclipse RCP application without having to dig in to extension points or other XML-based overrides, and you have the ability to customize any of it as much as you want. As you see it doesn&#8217;t take that much code as most of the big code is methods for copying files and checking directories.</p>
<h2><strong>All Code</strong></h2>
<p>Here are download links to all code referenced in this article:</p>
<div id="bulletlist">
<ol>
<li><a href="/files/posts/PickWorkspaceDialog.java">PickWorkspaceDialog.java</a></li>
</ol>
</div>
<p>(For the <code>Application.java</code> code please copy the big block in the article as it shows all code related to that class.)</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/01/12/rcp-workspaces/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Glazed Lists + SWT Tables == True</title>
		<link>http://hexapixel.com/2009/01/02/glazed-lists-swt-tables-true</link>
		<comments>http://hexapixel.com/2009/01/02/glazed-lists-swt-tables-true#comments</comments>
		<pubDate>Fri, 02 Jan 2009 18:01:19 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JFace]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=387</guid>
		<description><![CDATA[If you haven&#8217;t heard about Glazed Lists until now, it&#8217;s about time you do, because it&#8217;s probably the last tables and grid sorting/filtering API you will ever need. It will also be the last time you rip your hair out when someone asks you for a multi-sort-multi-thread-asynchronously-updated-filtered-unique-table (which happens all the time, right?). From here [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven&#8217;t heard about <a href="http://www.publicobject.com/glazedlists/">Glazed Lists</a> until now, it&#8217;s about time you do, because it&#8217;s probably the last tables and grid sorting/filtering API you will ever need. It will also be the last time you rip your hair out when someone asks you for a multi-sort-multi-thread-asynchronously-updated-filtered-unique-table (which happens all the time, right?). From here on out you&#8217;ll just be saying &#8220;oh, sure, give me 30 minutes&#8221; when you need to implement something along those lines. Sounds too good to be true doesn&#8217;t it? It is! So, what are Glazed Lists?</p>
<p>Glazed Lists is an API built on top of <code>java.util.List</code> which adds a notification framework and allows you to &#8220;stack&#8221; or &#8220;chain&#8221; lists together. This in and by itself may not sound so exciting. What this gives you though is the ability to take a Sorted list, stack it with a Filtered list, stack it with a Unique list, stack it with a asynchronously updated Unique list (and keep stacking), and whenever you modify the source list, it automatically tells the other lists in the chain to update so that their lists are always up to date. Last but not least, the list reports back to you and tells you to update your view with a specific list of changes. So imagine this &#8220;chained list&#8221; is the input for your TableViewer and perhaps you&#8217;re starting to see the potential.</p>
<p>I&#8217;ve been using Glazed Lists continuously for the last year, and it&#8217;s no short of astounding how powerful it is. I&#8217;ve used them on JFace TableViewers, The <a href="http://www.eclipse.org/nebula/widgets/grid/grid.php" target="_blank">Nebula Grid</a> widget, and the great rising-star <a href="http://nattable.org/drupal/" target="_blank">NatTable</a> which deserves it&#8217;s own article down the road (the only table widget I&#8217;ve found that can handle huge amounts of data without choking). On each of those widgets it was only a matter of creating a couple of smaller classes, a few lines of code, and I had the most powerful sorting and filtering API at my fingertips, ready for anything upper management could throw at me in terms of features. So often I see posts on the Eclipse Newsgroups asking about multi column sorting, and usually few concrete replies. &#8220;Glazed Lists&#8221; would be my reply.  To give an idea of what kind of sorting/filtering you can do, here&#8217;s a snapshot of  some of the available list types:</p>
<p><i>Sorted List. Filtered List. Unique List. Transformed List. Range List. Threshold List. Collection List. Freezable List. Popularity List. Separator List. Sequence List. Transaction List. Observable Lists</i>.. and the list goes on.</p>
<p>So instead of talking about how great they are in an entire post, how about some example implementations and actual code? Alright, let&#8217;s get to it!</p>
<p><span id="more-387"></span></p>
<p>To make this article &#8220;worth it&#8221; for everyone, I will cover implementing Glazed Lists on no less than 3 table/grid widgets. The standard JFace TableViewer (which is the least feature rich table component out there as it uses the SWT Table). The Nebula Grid widget (which is feature rich and very good, but has a big memory footprint on large tables) and the NatTable widget (as it will undoubtedly rise to fame soon with the next few versions (once some of the bigger bugs are ironed out)). Before you start copying and pasting code, all code is downloadable in each respective section and at the bottom of the article.</p>
<p>If you prefer to follow along or want to get a head start on downloading required jars, here are links to all the third party packages you might need:</p>
<div id="bulletlist">
<ol>
<li><a href="http://www.publicobject.com/glazedlists/glazedlists-1.7.0/" target="_new">Glazed Lists v1.7</a> (you do need this one)</li>
<li><a href="http://www.eclipse.org/nebula/widgets/grid/grid.php" target="_new">Nebula Grid (and Grid Viewer, required for the Nebula framework)</a></li>
<li><a href="http://sourceforge.net/project/showfiles.php?group_id=207809" target="_new">Nat Table v1.6.3 (grab both jars)</a></li>
<li><a href="http://logging.apache.org/log4j/1.2/download.html" target="_new">Apache Log4J</a> (Nat table needs this)</li>
<li><a href="http://commons.apache.org/downloads/download_lang.cgi" target="_new">Apache Commons Lang</a> (Nat table uses this internally for some odd reason)</li>
<li><a href="http://www.eclipse.org/downloads/" target="_new">Eclipse IDE / SWT</a></li>
</ol>
</div>
<p>Let&#8217;s start with the basics of Glazed Lists, as everything starts there.</p>
<h2><strong>Glazed Lists In a Nutshell</strong></h2>
<p>I could send you to the <a href="http://sites.google.com/site/glazedlists/documentation/tutorial" target="_new">Glazed Lists Tutorials</a> and tell you to follow those and come back, but I hate that kind of &#8220;teaching&#8221;, and the small &#8220;problem&#8221; with the tutorials is that they are all Java Swing based which is of little use to us (but by all means read them, they&#8217;re good). You might also want to check out the very good screen casts located <a href="http://publicobject.com/glazedlistsdeveloper/" target="_new">here</a> as they will give you a good idea of the different types of lists that can be used in Glazed Lists. In any case, everything in Glazed Lists starts with one thing, the root list. The root list contains all your items that you want to display before they are filtered or sorted. This list is probably in some random you-don&#8217;t-care order  which is perfectly fine. This list will serve as the input for all other chained lists. Think of it as layers, where the bottom layer is the raw list, and the higher up you go, the more refined and specific each layer is. So you have a sorting layer, a filter layer, etc. They can be active or not active, a bit like Photoshop. As we are using Glazed Lists, we need to take our root list and turn it into a Glazed Lists &#8220;EventList&#8221;, which is the Glazed Lists root-list equivalent. Here&#8217;s how that&#8217;s done:</p>
<pre>
<pre class="syntax-highlight:java">
List&lt;?&gt; rootList = .... // this comes from you
EventList&lt;?&gt; eventList = GlazedLists.eventList(rootList);
</pre>
</pre>
<p>As you can see everything uses Generics, just like normal Lists in Java 5+.</p>
<p>Any &#8220;normal&#8221; table in the UI-world will undoubtedly have Sorting and Filtering. With the code above we&#8217;re currently no different from any other plain old table implementation as we haven&#8217;t done sorting/filtering yet. So lets create the sorting/filtering layers that will be on top of the event list. We should think about order when it comes to our layers, as if we create a sorted list on top of a filtered list that&#8217;s not the same as creating a filtered list on top of a sorted list. Logically, we sort first, then apply a filter. To create our new lists we continue the code:</p>
<pre>
<pre class="syntax-highlight:java">
List&lt;?&gt; rootList = .... // this comes from you
EventList&lt;?&gt; eventList = GlazedLists.eventList(rootList);
SortedList sortedList = new SortedList(eventList, null);
FilterList(sortedList, new OurFilterMatcher());
</pre>
</pre>
<p>As you can see we keep using the last list as the input for the new list, as that&#8217;s our &#8220;chain&#8221;. The second parameter for the SortedList is the <code>Comparator</code> we want to use when sorting. I&#8217;m passing in <code>null</code> here to point out that it can be created when constructing the list (and not passing in null may actually throw an exception). Normally you don&#8217;t want the table sorted unless the user sorts it, so <code>null</code> makes sense. The <code>OurFilterMatcher</code> will be explained when we do the actual implementation, but just remember that it&#8217;s the &#8220;Matcher&#8221; that is used to filter a table (which is very much like a <code>ViewerFilter</code>).</p>
<p>There&#8217;s one more important aspect of Glazed Lists &#8211; locking. As lists can be updated on multiple threads (if you so wish) you need to tell the list when to &#8220;lock&#8221; and &#8220;unlock&#8221; so that only 1 thread is actively writing to the list at the same time. As such, it&#8217;s important we always do this when reading and writing to the list (and even if we don&#8217;t plan on multithread updates, it&#8217;s still good practice and takes little time to do). We could lock the lists when creating them even, but that&#8217;s a bit overkill, so keep en eye out for the locking code in the implementation part and in the framework code available for download. Glazed Lists even supports reading while writing, and their homepage has an example of an asynchronously updated list. Do check it out if you need advanced implementations. To give a quick example of locking/unlocking a list, here&#8217;s how it&#8217;s done:</p>
<pre>
<pre class="syntax-highlight:java">
_eventList.getReadWriteLock().writeLock().lock();
// ... modify list here ...
_eventList.getReadWriteLock().writeLock().unlock();
</pre>
</pre>
<h4><strong>The Callbacks</strong></h4>
<p>The whole idea of Glazed Lists is that when you modify the event list (and this is important: <strong>you <span style="text-decoration: underline;">always</span> modify the EventList</strong>!), it fires events to tell you what you need to change in your table implementation. Glazed has a lot of pre-built hooks for Swing, so there you don&#8217;t have to do much work, but as we use SWT we have to do pretty much all the work ourselves (great huh?). It&#8217;s not as bad as it sounds however. The callback interface that we care about here is <code>ListEventListener</code> which contains a method callback called <code>public void listChanged(ListEvent&lt;?&gt; listChanges)</code>. This list of changes <code>listChanges</code> tells us, <strong>in the correct order</strong>, what indexes and objects to update, delete and insert. It&#8217;s as easy as looping through that list, checking what the change is, and performing it. Here&#8217;s a barebones example of how it would look implemented:<a name="nutshell_code"></a></p>
<pre>
<pre class="syntax-highlight:java">
_filterList.addListEventListener(new ListEventListener&lt;?&gt;() {

	@Override
	public void listChanged(ListEvent&lt;?&gt; listChanges) {
		// get the list of changes (prior to looping, very important as it&#039;ll change as it&#039;s read)
		final List&lt;?&gt; changeList = listChanges.getSourceList();

		// go through all changes
		while (listChanges.next()) {
			// get the table index location of the change
			int sourceIndex = listChanges.getIndex();
			// get the change type
			int changeType = listChanges.getType();

			// update the table depending on the change type
			switch (changeType) {
				case ListEvent.DELETE:
					// delete row
					break;
				case ListEvent.INSERT:
					// insert row
					break;
				case ListEvent.UPDATE:
					// refresh row labels etc
					break;

			}
		}
	}

});
</pre>
</pre>
<p>That&#8217;s actually the most complex code we&#8217;ll be adding to make all of this work, and we can re-use that section of code for all our table widget implementations. </p>
<p>You might ask &#8220;why is the listener on the filter list if we were told to only modify the event list?&#8221;, which is a good and valid question. The answer is that if you were to listen on the event list instead, only base-level adds and deletes would be reported to you. As we also care about when stuff is re-ordered or moved in the list (which is what happens when users sort and filter) we want any list-changes to notify us. As our filtered list is the &#8220;topmost&#8221; or &#8220;last&#8221; list in the chain, it will get all notifications from all previous lists in the chain. Remember, all lists in the chain tell the next list down the line what changed (think of it as one-way gossip). By listening on the Filtered list we get all events, regardless on what list they happened. With that information we&#8217;re well on our way to putting Glazed into real use.</p>
<h2><strong>SWT TableViewer</strong></h2>
<p>Personally I was never a big fan of the SWT Table. A good thing about it is that it renders column headers natively, but it can be quite slow, sometimes buggy (first-column image support) and not very intuitive. It doesn&#8217;t support much customization and the second you need a table that can do a little more than a plain x/y grid, you soon hit those limitations head on. <a href="http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html" target="_new">Owner Draw</a> does help, but there&#8217;s still a lot of customization that is not possible. That said, as a &#8220;basic table&#8221; it does just fine and it&#8217;s getting better for each new SWT version. And of course, it&#8217;s native.</p>
<p>Normally when someone asks &#8220;can I sort a <code>SWT.VIRTUAL</code> table?&#8221; the answer is no or &#8220;not really&#8221;. The reason is that a virtual table only really knows what it shows in the current viewport (the visual area of the table), and how many items it has. Anything that you can&#8217;t see is not really &#8220;there&#8221;, except in memory. This obviously makes such a useful feature as <code>SWT.VIRTUAL</code> fairly useless in a sort scenario. The workaround in that case is to custom implement a sorter and replace the entire table content whenever the user sorts or filters. As we use Glazed Lists we don&#8217;t really care about this limitation, we&#8217;re working around it as we update the table with our changes whenever they occur thanks to the callback from Glazed Lists.</p>
<p>There&#8217;s a few special things we need apart from a &#8220;normal&#8221; Virtual TableViewer implementation. First, we&#8217;ll be using the <code>IStructuredContentProvider</code> for the Content provider. The <code>ILazyContentProvider</code> exists as well, but I had some odd issues with it in testing. If you want an example on how to create a virtual TableViewer, there&#8217;s a good snippet here: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet029VirtualTableViewer.java?revision=1.1&amp;view=markup" target="_new">Snippet029VirtualTableViewer</a>. In the <code>IStructuredContentProvider</code> we simply return the topmost layer (which is the FilterList) as follows;</p>
<pre>
<pre class="syntax-highlight:java">
class GlazedContentProvider implements IStructuredContentProvider {

	@Override
	public Object[] getElements(Object inputElement) {
		return _filterList.toArray();
	}

	@Override
	public void dispose() {
	}

	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
	}

}
</pre>
</pre>
<p>We also need to implement a Comparator which will be used by the SortedList, as well as a Matcher for the FilterList. The Comparator is a normal java Comparator whereas the Matcher is a Glazed Lists implementation. However, these are <a href="http://en.wikipedia.org/wiki/Immutable_object" target="_new">immutable</a> so they need to be new every time they are set on the respective lists. For the sake of simplicity, lets create an object called RowObject that represents one row in our table. All it does is keep track of the row number and it has a <code>getColumnText</code> method.</p>
<pre>
<pre class="syntax-highlight:java">
class RowObject {
	private int	_row;

	public RowObject(int row) {
		_row = row;
	}

	public int getRow() {
		return _row;
	}

	public String getColumnText(int col) {
		return &quot;&quot; + (_row + col);
	}
}
</pre>
</pre>
<p>With this all set up, we can now create the Comparator and Matcher. Lets start with the Comparator. As we&#8217;re basically returning an integer as display value for each cell in <code>getColumnText</code> we&#8217;ll use this as the basis for our comparison. Thus, our Comparator looks as follows;</p>
<pre>
<pre class="syntax-highlight:java">
class GlazedSortComparator implements Comparator&lt;RowObject&gt; {

	private int	_col;
	private int	_direction;

	public GlazedSortComparator(int col, int direction) {
		_col = col;
		_direction = direction;
	}

	@Override
	public int compare(RowObject o1, RowObject o2) {
		int ret = Integer.valueOf(o1.getColumnText(_col)).compareTo(Integer.valueOf(o2.getColumnText(_col)));

		if (_direction == SWT.DOWN)
			ret = -ret;

		return ret;
	}

}
</pre>
</pre>
<p>And now we create the Matcher which is used by the FilterList. The Matcher implementation in Glazed Lists asks us if a row object &#8220;matches&#8221; and not much more. This may seem confusing at first, but it&#8217;s quite similar to the <a href="http://help.eclipse.org/stable/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ViewerFilter.html" target="_new">ViewerFilter</a>. In our code we will have a textbox and a button that represents a &#8220;search&#8221; box. When the user presses the button we set a String field called &#8220;_filterText&#8221; to whatever the user entered, and then we set a new matcher on the FilterList. As such, our code implementation looks like this:</p>
<pre>
<pre class="syntax-highlight:java">
class GlazedMatcher implements Matcher&lt;RowObject&gt; {
	@Override
	public boolean matches(RowObject row) {
		for (int i = 0; i &lt; _table.getColumnCount(); i++) {
			if (row.getColumnText(i).indexOf(_filterText) &gt; -1)
				return true;
		}

		return false;
	}
}
</pre>
</pre>
<p>Now we can add two methods that actually do the updating when we filter and when we sort. Like this:</p>
<pre>
<pre class="syntax-highlight:java">
// update the table filter
private void updateFilter() {
	// if the search text is blank, remove the matcher
	if (_filterText == null || _filterText.length() == 0) {
		_filterList.setMatcher(null);
	}
	else {
		_filterList.setMatcher(new GlazedMatcher());
	}
}

// sorts a table on the given column
private void sortColumn(int col) {
	// do some normal UP/DOWN checking and updating
	int dir = SWT.UP;
	int current = _table.getSortDirection();

	TableColumn tc = _table.getColumn(col);
	if (_table.getSortColumn() == tc) {
		dir = (current == SWT.UP ? SWT.DOWN : SWT.UP);
	}

	_table.setSortColumn(tc);
	_table.setSortDirection(dir);

	// now tell the sorted list we&#039;ve updated
	_sortedList.setComparator(new GlazedSortComparator(col, dir));
}
</pre>
</pre>
<p>At this point we&#8217;re basically there. All that&#8217;s missing is a proper <code>listChanged</code> that reflects how we update a TableViewer. So with a few modifications to the code I posted in the <a href="#nutshell_code">nutshell section</a>, we get code that looks like this:</p>
<pre>
<pre class="syntax-highlight:java">
_filterList.addListEventListener(new ListEventListener&lt;RowObject&gt;() {

	@Override
	public void listChanged(ListEvent&lt;RowObject&gt; listChanges) {
		try {
			_table.setRedraw(false);

			// get the list PRIOR to looping, otherwise it won&#039;t be the same list as it&#039;s modified continuously
			final List&lt;RowObject&gt; changeList = listChanges.getSourceList();

			while (listChanges.next()) {
				int sourceIndex = listChanges.getIndex();
				int changeType = listChanges.getType();

				switch (changeType) {
					case ListEvent.DELETE:
						// note the remove of the object fetched from the event list here, we need to remove by index which the viewer does not support
						// and we&#039;re removing the object index location from the event list, not the filtered list
						_viewer.remove(_eventList.get(sourceIndex));
						break;
					case ListEvent.INSERT:
						final RowObject obj = changeList.get(sourceIndex);
						_viewer.insert(obj, sourceIndex);
						_viewer.replace(_filterList.get(sourceIndex), sourceIndex);
						break;
					case ListEvent.UPDATE:
						_viewer.replace(_filterList.get(sourceIndex), sourceIndex);
						break;
				}
			}

			// most important, we update the table size after the update
			_viewer.setItemCount(_filterList.size());
		}
		catch (Exception err) {
			err.printStackTrace();
		}
		finally {
			_table.setRedraw(true);
		}
	}

});
</pre>
</pre>
<p>The result, when combined with the rest of the necessary boilerplate code, looks like this:</p>
<p><img title="TableViewer using Glazed Lists" src="http://hexapixel.com/wp-content/uploads/2009/01/tv_glazed.gif" alt="tv_glazed" width="646" height="400" /></p>
<h4><strong>Download Code</strong></h4>
<p><a href="/files/posts/TableViewerGlazedExample.java">TableViewerGlazedExample.java</a></p>
<h2><strong>Nebula Grid</strong></h2>
<p>Whereas the normal SWT table only supports single column sort (unless you <a href="http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html" target="_new">owner draw</a>) the Nebula grid can do more. It can do multiple column sorting (visually), grouped columns, and other custom features not available in the default grid. The Nebula Grid has a Viewer implementation, but unfortunately at the time of writing this article, it does not support <code>SWT.VIRTUAL</code> mode. As Nebula sticks very much to the SWT API in terms of naming conventions and implementation, it should be little trouble to convert it over when it does.</p>
<p>Depending on how you look at it, you are about to get quite lucky. For my job I wrote an entire framework implementation wrapping Glazed Lists in a Nebula Grid. It&#8217;s much more generically implemented (with interfaces etc) than our TableViewer example which was written purely for this article. Because of this I don&#8217;t feel like actually ripping it apart into something smaller, so I will use this Framework as the basis for the examples. Thus, this implementation comes with the option to use both the GridViewer implementation (which might be good if you are doing smaller tables that don&#8217;t need Virtual mode) or the grid in <code>SWT.VIRTUAL</code> mode.</p>
<p>One of the bigger differences when we&#8217;re not in viewer mode, is that on the <code>DELETE, INSERT</code> and <code>UPDATE</code> we need to create <code>GridItems</code> instead of just telling the viewer that it&#8217;s changed. It&#8217;s a bit more clunky and object-heavy of course, but it&#8217;s not as bad as it sounds. The switch statement that we used in the previous example becomes this:</p>
<pre>
<pre class="syntax-highlight:java">
switch (changeType) {
    case ListEvent.DELETE:
        removeItem(sourceIndex);
        break;
    case ListEvent.INSERT:
        final IDataObject insert = list.get(sourceIndex);
        addItem(insert, sourceIndex);
        break;
    case ListEvent.UPDATE:
        final IDataObject update = list.get(sourceIndex);
        removeItem(sourceIndex);
        addItem(update, sourceIndex);
        break;
}
</pre>
</pre>
<p>As you can see each one calls a sub-method of the class, and those methods look like this:</p>
<pre>
<pre class="syntax-highlight:java">
private void removeItem(int index) {
	_parent.getTableViewer().remove(_parent.getTableViewer().getElementAt(index));
}

private void addItem(IDataObject msg, int index) {
	GridItem gi = new GridItem(_parent.getGrid(), SWT.NONE, index);
	gi.setData(msg);

	try {
		for (int i = 0; i &lt; _parent.getGrid().getColumnCount(); i++) {
			Color fg = msg.getForeground(i, index % 2 == 0);
			Color bg = msg.getBackground(i, index % 2 == 0);
			Font f = msg.getFont(i);
			String txt = msg.getColumnText(i);
			Image image = msg.getColumnImage(i);

			if (fg != null) {
				gi.setForeground(i, fg);
			}
			if (bg != null) {
				gi.setBackground(i, bg);
			}
			if (f != null) {
				gi.setFont(i, f);
			}
			if (txt != null) {
				gi.setText(i, txt);
			}
			if (image != null) {
				gi.setImage(i, image);
			}
		}
	}
	catch (Exception err) {
		err.printStackTrace();
	}
}
</pre>
</pre>
<p>In this code we use an interface <code>IDataObject</code> that is basically our <code>RowObject</code> code from before. This object has various getter methods for returning column texts, images, fonts and so on.</p>
<p>So how do we go about creating a Nebula Grid based grid with this framework? Mostly it&#8217;s the same way it&#8217;s done with pretty much any SWT widget, along the lines of:</p>
<pre>
<pre class="syntax-highlight:java">
GlazedGridViewer viewer = new GlazedGridViewer(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.VIRTUAL, this, true, null, null, false);
viewer.setAllowMultiColumnSort(true);
viewer.getGrid().setCellSelectionEnabled(true);
</pre>
</pre>
<p>Some pointers: The <code>this</code> parameter is an interface implementation of <code>IGenericGridTable</code> which forces the implementor of the code to include methods for returning a Comparator and a Matcher, like we created before in the previous example. <code>true</code> is the option to create the grid as a plain grid, or to false to create a viewer. The last 3 parameters are a String id used for saving/loading the table state (column order, sizes etc), an <code>IPreferenceStore</code> where it would be saved on, and lastly a <code>true</code>/<code>false</code> whether the table should be saving the state at all.</p>
<p>The framework comes with a default implementation of a Label provider and a Content provider which hooks into the <code>IDataObject</code>. They are created automatically depending on the table type you picked. Column creation is also handled by the framework as the column wrapping implementation allows for individual setting of if a column is sortable, movable, hide-able etc. The API looks like:</p>
<pre>
<pre class="syntax-highlight:java">
public GridViewerColumn(IGlazedGridViewer parentTable, String name, boolean frozen, boolean moveable, boolean sortable, boolean hideable) {
     ...
}
</pre>
</pre>
<p>But when you create a column you do it via the framework as:</p>
<pre>
<pre class="syntax-highlight:java">
GridViewerColumn col = viewer.addColumn(str, false, true, true, true);
col.getGridColumn().setWidth(100);
</pre>
</pre>
<p>And finally, to add objects and set the table input, it&#8217;s again much like the TableViewer, for example:</p>
<pre>
<pre class="syntax-highlight:java">
List&lt;IDataObject&gt; input = new ArrayList&lt;IDataObject&gt;();
for (int i = 0; i &lt; 1000; i++) {
	input.add(new OurIDataObjectClass(i));
}
viewer.setInput(input);
</pre>
</pre>
<p>I don&#8217;t think much more needs to be said about the framework. It has a lot of API in it already and a test class as well. I suggest you download it if you want to give it a go. </p>
<p><strong>Important:</strong> as I currently am not using the framework due to the fact that the Nebula Grid was too slow and memory hungry for what we needed it for (40,000+ rows) I converted the entire framework over to use a NatTable and kept the work going from there. It should be fine, but there may be some minor issues here and there as it was never fully tested. If you find problems and fix them, do send me the code so that everyone can benefit. For the NatTable implementation of the framework, that&#8217;s the next section of this article.</p>
<p>All put together, the test code looks like this when run (with shameless self-promo selection):</p>
<p><img title="Glazed Nebula Grid" src="http://hexapixel.com/wp-content/uploads/2009/01/tv_nebula.gif" alt="tv_nebula" width="681" height="382" /></p>
<p>No filter box in this example, but I think the TableViewer one shows how it works so it&#8217;s not necessary. A point worth making though is that all filters are <code>DataFilter</code> based (framework class). That class extends <code>ViewerFilter</code> so that if you need more than one table implementation, you can re-use your filters should you so wish. That filter also comes with &#8220;whole word&#8221;, &#8220;regular expression&#8221; and &#8220;case sensitive&#8221; filter/search options in the filter itself.</p>
<h4><strong>Download Code</strong></h4>
<p><a href="/files/glazed_nebula_framework.zip">Glazed Lists &#8211; Nebula Grid Framework</a></p>
<h2><strong>Nat Table</strong></h2>
<p>The <a href="http://nattable.org/drupal/" target="_blank">NatTable</a> Widget (Nat stands for Natalie, the girlfriend of the original widget author) is a fairly new Grid widget and one that I personally was quite impressed with after having researched pretty much all SWT grid widgets out there. It&#8217;s still in active development, and not everything is working 100% yet (grouped columns are problematic, some random drawing issues, frozen columns behave oddly, listeners are quite messy), but overall it&#8217;s in a good enough shape that we decided to use it in production. The reason I decided we should use it was simple; We needed a table that could deal with 40,000+ rows in 20+ columns without any lag or any drawing slowdowns whatsoever. It needed to be customizable and I wanted Glazed Lists on it. NatTable is inherently virtual, so you don&#8217;t tell it that it&#8217;s virtual, it just is. It only draws what you see in the viewport which makes redraws near instant and the overall feel is &#8220;snappy&#8221;.</p>
<p>The NatTable API is also quite different from most SWT widgets. Pretty much every part of the table can be extended or implemented in a custom way, and there&#8217;s a lot of classes and places to do this in. At the same time, the API feels sometimes half-finished as simple methods such as <code>selectAll()</code> are nowhere to be found, and trying to figure out how to do it can be a bit of a head-scratcher.  So, It takes a while to wrap your head around the API, but with help from a few examples on their homepage it shouldn&#8217;t be too much of a deal (and most of those kinds of methods are in the framework). The table is model driven, which I suppose is the third type of table model I see used in tables (first being no model and row-item based, second being a viewer on top of a row-item based grid).</p>
<p>All that said, I truly hope the current development team keeps this widget going (and from the looks of it it&#8217;s very active), because it just might be the best SWT grid-table currently out there. The Nebula Grid had huge potential, but development on it is slow going. I know Tom Shindl is doing work on it, but I don&#8217;t know what the roadmap is.</p>
<p>Ok, lets get going with the framework I&#8217;ve built for NatTable. It&#8217;s not complete, just like the Nebula Grid framework which it is based on, but it will get you a very long way. As this framework has gotten further it has more utility methods and automation than it&#8217;s predecessor. It will even mimic the Windows column headers through a custom header drawer if so desired. It also has full color-customization support via interfaces and so on. It would be a long list if I wrote it all here, so I suggest you check out the API.</p>
<p>To create a table using the framework, you can use various constructors, of which the biggest is:</p>
<pre>
<pre class="syntax-highlight:java">
public GlazedNatGridViewer(Composite parent, int style, IGenericNatGridTable generic, String tableId, IPreferenceStore store, boolean allowStateSaving, AbstractGlazedNatVisualConfig config) {
       ...
}
</pre>
</pre>
<p>You will notice the <code>IGenericNatGridTable</code> is the same interface as in the Nebula Grid framework and works the same way (just different name). The last parameter, <code>AbstractGlazedNatVisualConfig</code> is if you want to pass in custom settings for colors, fonts, widths, heights etc. A whole load of things can be customized, or you can stick to the defaults (<code>DefaultGlazedNatVisualConfig</code>).</p>
<p>In our test class we will do the same as we&#8217;ve done in the previous examples, we&#8217;ll create some columns, some row data and do a sort. Using the framework we create a new table as follows:</p>
<pre>
<pre class="syntax-highlight:java">
GlazedNatGridViewer viewer = new GlazedNatGridViewer(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION, this, new DefaultGlazedNatVisualConfig());
viewer.setAllowMultiColumnSort(true);

for (int i = 0; i &lt; 10; i++) {
	NatGridViewerColumn col = viewer.addColumn(&quot;Column &quot;+i, false, true, true, true);
	col.setDefaultWidth(100);
}

List&lt;OneRow&gt; input = new ArrayList&lt;OneRow&gt;();
for (int i = 0; i &lt; 1000; i++) {
	input.add(new OneRow(i));
}

viewer.setInput(input);
</pre>
</pre>
<p>Our <code>OneRow</code> class implements <code>IDataObject</code> which contains getters for all things table related (column text etc). It also contains a getter specifically for returning a value that should be used when comparing column data when sorting. By default we simply return the same column text as the visible-to-user text:</p>
<pre>
<pre class="syntax-highlight:java">
class OneRow implements IDataObject {

	private int _row;

	public OneRow(int row) {
		_row = row;
	}

	@Override
	public String getColumnText(int column) {
		return &quot;&quot;+(_row+column);
	}

	@Override
	public String getSearchMatchText(int column) {
		return getColumnText(column);
	}

	...
}
</pre>
</pre>
<p>The multi column sort feature is already built in, and uses Glazed Lists ability to chain comparators. So whenever you sort more than one column, it will ask for a Comparator for each sorted column, and combine them in the order that you sorted the columns. You multi-sort by holding down the shift key to add more columns, and I&#8217;ve also added so it draws a number on the column header for displaying which order it was sorted in. The sort happens as soon as you let go of the shift key (and you can modify the columns by pressing the shift key again before clicking the column header).</p>
<p>Running the test class we get a table that looks like this:</p>
<p><img title="Glazed Nat Table Viewer" src="http://hexapixel.com/wp-content/uploads/2009/01/tv_nat.gif" alt="Glazed Nat Table Viewer" width="625" height="342" /></p>
<p>That pretty much sums it up for the Nat Table. Regardless of what table implementation you are going with or decide to go with, I&#8217;m sure you will agree that the power and simplicity of Glazed Lists is amazing. And we&#8217;ve only scratched the surface on it here. For much more information and examples with deeper complexity I suggest visiting the homepage and checking the Glazed Lists API. They have some built-in support for SWT as well (such as putting your updates on the UI thread), so they&#8217;re not 100% Swing-based even though most of their pre-implemented table-realted items are for Swing components. </p>
<h4><strong>Download Code</strong></h4>
<p><a href="/files/glazed_nat_framework.zip">Glazed Lists &#8211; Nat Table Framework</a></p>
<h2><strong>Closing words</strong></h2>
<p>This was a long article. It took me 2 full days to write and much longer if you count the hours put into creating both frameworks. My hopes is that you will find the article and Glazed Lists useful in your future table and grid implementations, and that this wonderful package becomes as part of your projects as <a href="http://www.miglayout.com/">MigLayout</a> or other &#8220;must have&#8221; API&#8217;s that make our lives coding UI&#8217;s much easier. Personally I cannot live without Glazed Lists, and I only wish I had found out about them sooner. </p>
<p>And again, I highly recommend the <a href="http://publicobject.com/glazedlistsdeveloper/">screen casts</a> for more information on each type of list you can create.</p>
<p>Do let me know if you spot errors in the article, it&#8217;s hard to cover everything on the first try. I will put these files + a link to this post into the Projects section later as well.</p>
<h2><strong>All Code</strong></h2>
<p>Here are download links to all code referenced in this article:</p>
<div id="bulletlist">
<ol>
<li><a href="/files/posts/TableViewerGlazedExample.java">TableViewer code</a></li>
<li><a href="/files/glazed_nebula_framework.zip">Glazed Lists &#8211; Nebula Grid Framework</a></li>
<li><a href="/files/glazed_nat_framework.zip">Glazed Lists &#8211; Nat Table Framework</a></li>
<li><a href="/files/glazed_nebula_and_nat_frameworks.zip">Glazed Lists &#8211; Both Frameworks Combined</a></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/01/02/glazed-lists-swt-tables-true/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Managing Experienced Developers</title>
		<link>http://hexapixel.com/2008/12/29/managing-experienced-developers</link>
		<comments>http://hexapixel.com/2008/12/29/managing-experienced-developers#comments</comments>
		<pubDate>Mon, 29 Dec 2008 18:46:10 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Project Management]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=322</guid>
		<description><![CDATA[First, the mandatory Dilbert cartoon&#8230; Having worked in many companies over the years there are a few things I know better than my managers, and the longer I&#8217;m in this business the more frustrated I get when things are simply not working the way they should due to bad management. If I as a senior [...]]]></description>
			<content:encoded><![CDATA[<p class="aligncenter">First, the mandatory Dilbert cartoon&#8230;</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-345" title="dilbert_managers" src="http://hexapixel.com/wp-content/uploads/2008/12/dilbert_managers.gif" alt="dilbert_managers" width="592" height="213" /></p>
<p>Having worked in many companies over the years there are a few things I know better than my managers, and the longer I&#8217;m in this business the more frustrated I get when things are simply not working the way they should due to bad management. If I as a senior programmer have to step in to do actual project management because my technical project manager fails to do it, something is wrong. Unfortunately this is more common than it should be. A big issue is that managers that are put in charge of development teams are often under-educated when it comes to development and the development process. In fact, they may know nothing about programming at all, and they&#8217;re thrown into a world of developers who can build them anything they request &#8211; assuming upper management has a good plan on what needs to be built.</p>
<p>Why and how these managers end up in a technical management positions is always the question, but any programmer who&#8217;s been around for a while can usually sniff out the bad ones in mere seconds. A good manager is a mediator, someone who knows they may not always know better, but listens to their team, suggests solutions based on what the team has told them and mediates between the dev team and the rest of the company (and upper management). A good manager could be compared to a good army commander. The troops know they can trust them, and will follow them into battle knowing that all decisions are calculated and weighed and probably the best ones. A bad manager however is one who undoubtedly will cause massive team issues and communication breakdown. In the troop scenario the team would undoubtedly get into serious trouble, and if it were a pirate ship, mutiny would soon ensue.</p>
<p>Down the road bad management leads to anger and frustration, and ultimately to the dark side. I&#8217;ve been in many meetings where the programming team starts talking tech issues and the manager sits silently like a question mark watching a tennis match because they have no idea what people are talking about. This is very bad, and a sign of probable project failure down the road (or lots of code re-writes due to miscommunicated features). It&#8217;s OK to not understand <em>everything</em>, but if you manage programmers (especially experienced programmers) you need to be someone who understands the field, and understands it well. A developer who knows that their manager does not understand what they tell them will start communicating less and less, and in the end will probably stop altogether as it does not help them in any way. This leads to a team that is disconnected from management, and undoubtedly a manager who has no clue about the status of the project.</p>
<p>Another issue, seemingly common, is that the product manager (who is literally in charge of the product and the outcome thereof) does not even know what the product is. This usually leads to constant feature changes, and a very angry team. A lot of this can be solved with a good specification early on, but with deadlines looming and budgets shrinking, tech specs are a dying breed.</p>
<p>There was a great thread on Slashdot a few weeks back called &#8220;<a href="http://ask.slashdot.org/article.pl?sid=08%2F12%2F12%2F1947251&amp;from=rss" target="_new">Managing Seasoned Developers</a>&#8221; which is the basis for this post, and despite the random seasoning jokes, there is some really great information in there. As I don&#8217;t expect you to go through that thread to dig out the good stuff, I decided to take the best parts and make a list of &#8220;What a good development team manager should and should not do&#8221;. I also added a few other worthy entries from other places and adjusted some to reflect my own experiences.</p>
<p><span id="more-322"></span><br />
<strong>How to deal with experienced developers as a manager (in random order)</strong>:</p>
<div id="bulletlist">
<ol>
<li>Focus on getting them what they need, staying out of their way, and keeping management related items out of their way. If you want them to manage, make them managers. They can&#8217;t do both at the same time, and if they are forced to do so, they will most likely get quite frustrated and possibly angry.</li>
<li>Professionals typically don&#8217;t enjoy working for someone that doesn&#8217;t give them the respect that they&#8217;ve earned. When this happens your good employees will no longer feel good about the job they are doing and go find a new one. Requiring silly things of your good people is a sure way to see them leave for something better.</li>
<li>Unless your project is 100% exciting to everyone on the team, the answer is, you won&#8217;t be able to manage it without adding some junior programmers. An engineer with 10 years of experience and multiple death marches under his belt will simply find it hard to get excited about the mundane. That&#8217;s not what he&#8217;s there for. He&#8217;s there to take on the big challenges, design stuff that works and implement it in a way that he&#8217;s not embarrassed by it five years from now. If you can&#8217;t accept that, he will surely walk out the door soon.</li>
<li>A company that lacks or literally blocks communication between employees on the same team is not a company worth working for. Communication is the cornerstone of a successful team. A quiet project is as bad as a quiet patch in the forest, you just know something is wrong and &#8220;dead&#8221; around the corner.</li>
<li>Good software engineers enjoy solving tough problems. So present them with the problems you are trying to solve and let them come up with their own solutions. If you don&#8217;t understand the technology, don&#8217;t be afraid or ashamed to ask. Read up on what they&#8217;re proposing. Chances are they are suggesting technology that won&#8217;t come back and bite you in the ass 5 years down the road.</li>
<li>The manager is a domain expert, and can evaluate the product as it is being created. If she can&#8217;t do this, or relies on self-assessment of her reports, the product is going to suck or fail.</li>
<li>Don&#8217;t say that something is undoable if you do not know if it&#8217;s actually doable or not. Ask the developers! They will certainly know if it&#8217;s a possible or impossible task. Not asking them and instead making up things makes you look very dumb.</li>
<li>Chit-chatting and making jokes when you can&#8217;t even manage a project makes you look horrible in the eyes of a good developer. If you can&#8217;t manage them or the team, do you really think they will appreciate that you&#8217;re trying to get on their good side?</li>
<li>The end user of the product is the client, not the project manager. Don&#8217;t expect to know what the client wants without asking them, about everything. There&#8217;s nothing more irritating when a client comes back and says they want it a completely different way, and the engineer has to re-write half the code because you didn&#8217;t ask them beforehand what they wanted.</li>
<li>Never criticize them for something you also fail at. Instead, announce that you&#8217;re looking to improve that aspect in yourself and they&#8217;ll get the message.</li>
<li>When your best engineers have to lead the project because the manager doesn&#8217;t know what they&#8217;re talking about, it&#8217;s time to find someone who can actually manage the project, or send the manager to training so that they can keep up.</li>
<li>If there are issues in the product that are only brought up at the next team meeting, don&#8217;t bring them up unless you have the guts to tell the developer(s) with enough time beforehand so they have time to look at those issues and possibly fix them instead of hearing them as &#8220;issues&#8221;. If they&#8217;re big issues, bring them up right away. If they&#8217;re small issues, make a list and go over it with the developers.</li>
<li>Be open to criticism and be willing to change course in response to it.</li>
<li>The best developers need a set of requirements, a deadline, a good working environment and caffeinated drinks. Not much more. They will deliver.</li>
<li>There&#8217;s nothing better than a good developer who can design, code, document and communicate, and does not need constant supervision. On the other hand, there&#8217;s nothing worse than one that pretends to do those things and turns out to be a disaster for the project. If there are employees who fall into the latter category on more than one occasion, it&#8217;s probably time to reconsider their placement or job.</li>
<li>Managers are not programmers just like programmers are not managers. It doesn&#8217;t matter if you programmed in the past, you&#8217;re a manager, get used to it. So please do not embarrass your team by trying to make code changes or additions. Leave it to them. They will do it in 1/10th of the time and with 1/10th of the bugs.</li>
<li>Use technologies (bugtracking etc) that are easy to use and easy to update. Overly complicated and complex software to do &#8220;simple tasks&#8221; will do nothing but slow down the entire development process. This is especially true for complex version-control software.</li>
<li>Feedback feedback feedback. Don&#8217;t overdo it on the pats on the back, but for the love of god, don&#8217;t forget them. If an engineer goes above and beyond, they expect to be treated like it and respected.</li>
<li>Think &#8220;How would I like to be treated?&#8221;. The answer is most likely &#8220;With respect, open communication, acknowledgment of work done, incentive for above and beyond&#8230;&#8221;. Get to learn who they are.</li>
<li>If you&#8217;re part of a bigger team (10+) and rarely or never show up at team meetings, don&#8217;t expect that any of your words will mean much to the team. They know you&#8217;re not there, and you&#8217;re letting the team down. Coming along later and saying &#8220;great job!&#8221; is a slap in the face and viewed as you getting all the credit for their hard work. Never do this.</li>
<li>To a seasoned programmer, you as a manager are redundant unless you can prove otherwise. If you fail at your task, they will work around you and go above your head with all matters until they get heard. This will come back to bite you sooner or later.</li>
<li>When experienced programmers learn that other lesser-individuals earn more than them (they will), either deal with it swiftly or watch them walk out the door. Salaries, just like interesting projects, are extremely important. A &#8220;very good&#8221; programmer expects to be paid &#8220;very well&#8221;, as he or she is most likely pulling more than their own weight on all the projects they are involved with.</li>
<li>Claiming your best programmers have to be at work on certain dates and plan their vacations long times in advance because of risk of &#8220;failure&#8221; means you need more good people on your team. Everyone needs vacation, it&#8217;s what makes us come back to work harder. Work them to death or set limitations and you will only increase their stress level.</li>
<li>Every time you interrupt someone in the middle of their task, you probably wasted 10 minutes more for them to get back &#8220;into it&#8221;.</li>
<li>Good developers can multitask like a quad-core processor. If you think they&#8217;re not working because they&#8217;re browsing a website not work-related, be careful before you judge. They&#8217;re most likely taking a 1 minute brain pause, compiling in the background, or upgrading the kernel with their left hand. Let them continue, because those small pauses may be all they get while their brains work overtime.</li>
<li>Follow and adjust to <a href="http://www.codinghorror.com/blog/archives/000666.html" target="_new">The Programmer&#8217;s Bill of Rights</a>. Nothing else needs to be said about this, it speaks for itself.</li>
</ol>
</div>
<p>It&#8217;s also worth mentioning that managers need to be told some of these things (their weak spots), so don&#8217;t be afraid to put your foot down, it just might make them better!</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2008/12/29/managing-experienced-developers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
