<?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; SWT</title>
	<atom:link href="http://hexapixel.com/tag/swt/feed" rel="self" type="application/rss+xml" />
	<link>http://hexapixel.com</link>
	<description>Programming, Eclipse, SWT and everything inbetween</description>
	<lastBuildDate>Tue, 06 Sep 2011 13:21:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>XAML in SWT / Where The Ribbon Is</title>
		<link>http://hexapixel.com/2010/01/06/xaml-in-swt-and-where-the-ribbon-is</link>
		<comments>http://hexapixel.com/2010/01/06/xaml-in-swt-and-where-the-ribbon-is#comments</comments>
		<pubDate>Wed, 06 Jan 2010 15:04:11 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=826</guid>
		<description><![CDATA[I get loads of traffic and email thanks the Ribbon. It&#8217;s truly an alpha project that went completely beyond what I had imagined. It&#8217;s exciting of course, but as much as it should give me a warm fuzzy feeling, it actually makes me rather nauseous. The thing is, a lot of the code is a [...]]]></description>
			<content:encoded><![CDATA[<p>I get loads of traffic and email thanks the Ribbon. It&#8217;s truly an alpha project that went completely beyond what I had imagined. It&#8217;s exciting of course, but as much as it should give me a warm fuzzy feeling, it actually makes me rather nauseous. The thing is, a lot of the code is a total mess, it&#8217;s embarrassing, and I&#8217;ll freely admit it. It was never written as a &#8220;thought out&#8221; project, it was simply written as a not-so-quick &#8220;test&#8221; to see if it was possible to do a Ribbon component in pure SWT. The answer was &#8220;kind of&#8221;, and that&#8217;s where it got left off.</p>
<p>After having worked with <a href="http://silverlight.net/" target="_new">Microsoft Silverlight</a> and <a href="http://en.wikipedia.org/wiki/Extensible_Application_Markup_Language" target="_new">XAML</a> lately I realized how simple XAML makes it to do stuff that I spent hours writing code for in the Ribbon. For example; rounded corners, gradient borders, multi-gradient fills, etc. It&#8217;s a pleasure to work with, easy to change, and it moves you forward at a good pace &#8211; and that&#8217;s how I feel it should be. I doubt anyone would download the Ribbon source as it is now, look at the render classes and think &#8220;great, I&#8217;ll make a change riiiight here&#8221;, it&#8217;s just too complicated and non-customizable. A user wanting to change colors would have to spend hours, days even, just to figure out what pixel is drawn where, and when I look at the code now, I get the same feelings.</p>
<p>Instead of continuing work on the Ribbon to finish &#8220;the mess&#8221;, I decided that if it was ever going to finish the project and take it out of Alpha, I was going to do all the rendering stuff the right way. And thus started a little test project with Brushes with the intention that if I could make things as easy as writing XAML, I could write all the Ribbon widgets in no-time.</p>
<p><span id="more-826"></span><br />
<h3>Brushes</h3>
<p>A Brush object in XAML (and in a lot of other languages) is like a paint brush, it defines a direction and a stroke, colors, etc. The Ribbon basically uses a whole ton of Brushes.</p>
<p>Here&#8217;s a quick list of the things that the Ribbon currently uses lots of:</p>
<ul>
<li>2-color and Multi-color gradients in Horizontal and Vertical orientation, there are no diagonal or radial gradients (although brushes in XAML support any angle).</li>
<li>&#8220;Border&#8221; controls that contain other controls (pretty much all controls have some sort of border around them). A Border control in <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation" target="_new">WPF</a> is a control that can contain only 1 other control, and it can display a border and a background and allows for rounding of the borders.</li>
<li>Various paddings and margins between controls to space them out between one another.</li>
<li>Colors, colors and more colors.</li>
</ul>
<p>If you think about it, that&#8217;s pretty much any control in an normal GUI library as at some level of the OS, there will be a programmatic &#8220;pen&#8221; that is drawing everything you see, pixel by pixel. Everything built on top of that is convenience to the user. And how many people know how to programatically draw a gradient between 2 colors if there isn&#8217;t an API to do it with? Probably very few.</p>
<p>(If you want to see a fully functional Ribbon in Silverlight (built on XAML) do a google search for &#8220;SandRibbon&#8221;. I&#8217;d link to it here but it&#8217;s commercial and costs a fortune, so I don&#8217;t feel like promoting it with a cross-link.)</p>
<h3>Multi-color Gradients</h3>
<p>My &#8220;Pseudo&#8221; code that I started from to &#8220;realize&#8221; this was the following:</p>
<pre>
<pre class="syntax-highlight:java">
LinearGradientBrush yrb = new LinearGradientBrush(new DPoint(0.5, 0), new DPoint(0.5, 1));
yrb.addGradientStop(new AlphaColor(&quot;#FFfff900&quot;), 0);
yrb.addGradientStop(new AlphaColor(&quot;#FFf90005&quot;), 0.5);
yrb.addGradientStop(new AlphaColor(&quot;#FF1100ad&quot;), 1);
</pre>
</pre>
<p>It&#8217;s very WPF/XAML, and what it says is &#8220;Create a brush that will draw a gradient vertically (each DPoint is x/y coordinates of how the fill should draw), add 3 color stops, one at 0%, one at 50% and one at 100%&#8221;. </p>
<p>XAML, by the way, for a typical LinearGradientBrush looks like this:</p>
<pre>
<pre class="syntax-highlight:xml">
&lt;LinearGradientBrush EndPoint=&quot;0.5,1&quot; StartPoint=&quot;0.5,0&quot; x:Key=&quot;ToolbarButtonBackgroundStrokeNormal&quot;&gt;
     	&lt;GradientStop Color=&quot;#FFfff900&quot; Offset=&quot;0&quot;/&gt;
        &lt;GradientStop Color=&quot;#FFf90005&quot; Offset=&quot;0.5&quot;/&gt;
        &lt;GradientStop Color=&quot;#FF1100ad&quot; Offset=&quot;1&quot;/&gt;
&lt;/LinearGradientBrush&gt;
</pre>
</pre>
<p>If we were to do this in Photoshop it&#8217;d look exactly like this (on a 400&#215;400 canvas):</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2010/01/gradient.jpg"><img src="http://hexapixel.com/wp-content/uploads/2010/01/gradient.jpg" alt="gradient" title="gradient" width="400" height="400" /></a></p>
<p>To support multi-color gradients when using pattern fills (as SWT doesn&#8217;t), I had to write some code that split each section that I intend to fill into smaller rectangles and fill each one. Each section is 2 colors. So in the above case, we have 2 patterns we need to create, one from 0% to 50% and one from 50% to 100%. In the picture this would be from 1 to 2, and from 2 to 3.</p>
<p>Implementing it wasn&#8217;t that hard, and despite the code not being that long I think it&#8217;s easier you look at the source itself if you want the details as it&#8217;s a bit spread out. The source is at the bottom of the article.</p>
<h3>A SWT Border Control</h3>
<p>The &#8220;Border&#8221; control in WPF takes a few interesting attributes. One is the Brush that is used to fill the border, the second is the Brush used to fill the background. Then it allows for a setting the border &#8220;roundness&#8221;, the padding and the margin, and a few other things. All of that is mostly getters/setters and in the end we will have a <code>GraphicsObjectRenderer</code> class that deals with actually drawing it. If there was a border control in SWT it might look a bit like this:</p>
<pre>
<pre class="syntax-highlight:java">
Border b = new Border(parentControl);
b.setBorderBrush(ourBorderBrush);
b.setFillBrush(ourFillBrush);
b.setBorderThickness(1);
b.setCornerRadius(20);
b.setWidth(100);
b.setHeight(100);
b.setMargin(new Margin(50));
</pre>
</pre>
<p>Pretty straight forward.</p>
<p>The result from running this code looks something like this:</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2010/01/bordertest.jpg"><img src="http://hexapixel.com/wp-content/uploads/2010/01/bordertest.jpg" alt="bordertest" title="bordertest" width="400" height="399" /></a></p>
<h3>Oh no, Issues&#8230;</h3>
<p>This is how far I got before I hit a wall. I actually started writing the article as I wrote the code because I was quite excited how seemingly well it worked. So what halted me? A few bugs in SWT. Normally a lot of things can be worked around if they don&#8217;t work 100% as intended, however, the bugs I came across were not of that type. The main issues are as follows:</p>
<ul>
<li>Pattern fills in SWT start drawing the pattern in the wrong place. I&#8217;ve filed a bug for this which can be found <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=297467" target="_new">here</a>. This one is rather critical as most of the brush drawing depends on it.</li>
<li>A rounded rectangle is not drawn in the same way as a round rectangle, causing the border around it to be in weird places around the rectangle itself. An old bug is filed <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=181676" target="_new">here</a>.</li>
<li>Other GC draw-related bugs.</li>
</ul>
<h3>Conclusion</h3>
<p>Probably not the conclusion you or I wanted, but as I see it, I cannot really continue this project until the bugs are fixed (or worked around), and considering GC-related bugs are probably low on the fix-list, the Ribbon will have to sleep for a while longer, along with this project. AWT has a very good <code>MultipleGradientPaint</code> implementation and I successfully manged to convert AWT drawings to SWT, but the AWT code is rather slow and converting it over is also slow, so it&#8217;s not really an option.</p>
<h3>Code</h3>
<p>If you want to play with the code I have so far, you can download it here. Under the &#8220;test&#8221; package directory you&#8217;ll find various classes. <code>BorderTester.java</code> is the main test class. The code is truly &#8220;as is&#8221;, it&#8217;s just zipped up from what I had at the time I ran into issues.</p>
<p><a href='http://hexapixel.com/wp-content/uploads/2010/01/com.hexapixel.advanced.graphics.zip'>Download Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2010/01/06/xaml-in-swt-and-where-the-ribbon-is/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Printing SWT Tables with PaperClips</title>
		<link>http://hexapixel.com/2009/09/18/printing-swt-tables-with-paperclips</link>
		<comments>http://hexapixel.com/2009/09/18/printing-swt-tables-with-paperclips#comments</comments>
		<pubDate>Fri, 18 Sep 2009 06:56:33 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[Printing]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=563</guid>
		<description><![CDATA[In this article I will explain how to print a table using PaperClips (as of this writing PaperClips is in process of moving to the Eclipse Nebula project). When I say print, I mean print literally, as in printing on a printer. PaperClips is a lightweight API that makes building printable pages very easy. It [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I will explain how to print a table using <a href="http://code.google.com/p/swt-paperclips/" target="_new">PaperClips</a> (as of this writing PaperClips is in process of moving to the <a href="http://www.eclipse.org/nebula/" target="_new">Eclipse Nebula project</a>). When I say print, I mean print literally, as in printing on a printer. PaperClips is a lightweight API that makes building printable pages very easy. It uses a simple and logical structure that has many useful features and it&#8217;s surprisingly flexible. One of the many possibilities is the ability to print tables quite nicely as it has a &#8220;GridPrinter&#8221; (which is what this article will cover. But you can of course use PaperClips to print nearly anything). </p>
<p>The code for this article will let you print pretty much any SWT table widget of your choice as all you need to do is wrap your table in an interface and off you go. But since this is an article, let&#8217;s stick to the plain old SWT table for the sake of the demo. I will mostly go over important snippets of the code and the rest you can download and re-use (download link is at the bottom of the article). </p>
<p>Let&#8217;s list a few things we want to achieve with our implementation:</p>
<ul>
<li>Print preview (PaperClips gives us most of this already).</li>
<li>The option to print either just a selection or all items.</li>
<li>Customizable header and footer.</li>
<li>Printing table with column sizes as they are in the table.</li>
<li>Options to specify if headers are printed, where lines are drawn and so on.</li>
</ul>
<p><span id="more-563"></span></p>
<p>The table that we intend to print for this article looks like this (just run the <code>Tester.java</code> class in Eclipse):</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2009/09/pp1.gif"><img src="http://hexapixel.com/wp-content/uploads/2009/09/pp1.gif" alt="Table Screenshot" title="Table Screenshot" width="558" height="286" /></a></p>
<p>We use <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet38.java?view=co">Snippet38</a> and add a button at the bottom for printing.</p>
<h2><b>Understanding Paperclips</b></h2>
<p>It&#8217;s probably ideal that you understand the PaperClips syntax before you keep reading. PaperClips has certain letters and things that let you specify column widths, how things span and wrap etc. Please do a quick scan of <a href="http://code.google.com/p/swt-paperclips/wiki/GridPrint" target="_new">this page</a> if you are unfamiliar with the syntax. It will take no more than a few minutes to learn, it&#8217;s that easy.</p>
<h2><b>Creating a GridPrint</b></h2>
<p>As mentioned, the GridPrint class is basically a class for printing grids. It will allow you to set things such as columns, headers etc. Think of it as a table widget, but as if it was drawn on a piece of paper.</p>
<p>Our main class that will handle all the printing will be called <code>GridPrinter.java</code>, and the constructor looks like this:</p>
<pre>
<pre class="syntax-highlight:java">
public PrintResultCode printTable(IGenericTable tableImpl, boolean printSelectionOnly, boolean showPreview, String docTitle, final Shell parentShell) {
 ...
}
</pre>
</pre>
<p>The <code>IGenericTable</code> is an interface that you use to wrap the SWT table you want to print. It contains simple methods such as getting the name or width of a column, or an item on a specific row (methods that most table implementations already have). The second attribute defines whether everything is printed or only what the user has selected is printed. The third defines if we show a Print Preview dialog or just print straight to the printer. The fourth is the title of our document that we are printing and finally it&#8217;s the shell that will be the parent shell of the print preview dialog (if we are previewing). </p>
<p>Now that we have all the &#8220;data&#8221; we need, the first thing we want to do is to create the column headers. This is done via a very short loop;</p>
<pre>
<pre class="syntax-highlight:java">
for (int i = 0; i &lt; cols.size(); i++) {
    String name = concat(tableImpl.getColumnTitle(cols.get(i)), widths.get(i), concatGc, headerFont);
    print.addHeader(new TextPrint(name, _headerFontData));
}
</pre>
</pre>
<p>We get the table column text and then concatenate it if it&#8217;s longer than the actual width of the column itself (just like the table does as a widget). <code>print</code> is our GridPrint, and to that we simply say &#8220;add this header&#8221;, and then create a <code>TextPrint</code> with the name and our specified header font. A TextPrint can be thought of as a basic cell that contains text with or without a font. Do note that pretty much everything is a &#8220;print&#8221;, so you can add a GridPrint to a GridPrint to a GridPrint etc. You get the idea.</p>
<p>Now that we have our table column header added, let&#8217;s add the cell data that goes below.</p>
<pre>
<pre class="syntax-highlight:java">
for (IDataObject gi : sel) {
    for (int i = 0; i &lt; cols.size(); i++) {
        String colText = gi.getColumnText(cols.get(i));
        if (colText == null) {
            colText = &quot;&quot;;
        }
        String text = concat(colText, widths.get(i), concatGc, cellFont);
        print.add(tp(text, _cellFontData));
    }
}
</pre>
</pre>
<p>It&#8217;s nearly identical but instead of adding it as a header to the GridPrint we just add it normally. We do the same concatenation as in the header as we want to print exactly what the table looks like (so if the user resizes a column in the table widget, that&#8217;s the size that is used for the printed version as well). The <code>sel</code> array represents all selected items. If we called our constructor with the option to print all items, it will contain all items, and if we called it and said &#8220;only print the selected items&#8221;, it will contain those. The code also contains logic for spacing out cells, so if you were to select individual cells like this&#8230;</p>
<pre>
# - - # - -
- # # - - -
- - - - - #
</pre>
<p>&#8230; it would print it in the way you would expect it to.</p>
<h2><b>Multiple Pages and Large Prints</b></h2>
<p>As the code is not a human and has no idea of how big your table actually is, it&#8217;s quite possible it spans multiple pages both horizontally or vertically. A GridPrint does not handle this by default. But remember that pretty much all print-classes can be children of each other? To support large prints (basically anything beyond the size of a single printed sheet of paper), we need to wrap our page (the GridPrint) in a <code>BigPrint</code>. Just by doing that via a simple&#8230;</p>
<pre>
<pre class="syntax-highlight:java">
BigPrint big = new BigPrint(print);
</pre>
</pre>
<p>&#8230; we can now support multiple pages. Easy wasn&#8217;t it? </p>
<h2><b>Headers, Footers and Spacing</b></h2>
<p>Normally you will want headers and footers on the printed paper. The header tends to contain your company logo and the document title. The footer usually contains what page it is and perhaps a date or such. To accommodate this, there is a <code>PagePrint</code> class that will let you customize all of these aspects. To use it we want that to be our &#8220;outermost&#8221; parent, so the order is: PagePrint -&gt; BigPrint -&gt; GridPrint.</p>
<p>Here&#8217;s how we create the PagePrint:</p>
<pre>
<pre class="syntax-highlight:java">
PagePrint pp = new PagePrint(new PrintHeader(_printHandler, docTitle), big, new PrintFooter(getFooterText()));
pp.setHeaderGap(9);
pp.setFooterGap(18);
</pre>
</pre>
<p>In the constructor, we tell it &#8220;here&#8217;s our header, our BigPrint and our footer&#8221;. We also tell it how much spacing we want between the header/footer and the content of the page. It&#8217;s usually nice to space them out slightly so it&#8217;s not too packed together. </p>
<p>The header and footer classes are both classes that implement the PaperClips <code>PageDecoration</code> interface. They&#8217;re very simple to use and only require one method. All this method forces you to return is a &#8220;Print&#8221; that represents your header (or footer). They can be of any print-class you like, a GridPrint, a TextPrint, etc. For example, here&#8217;s our header:</p>
<pre>
<pre class="syntax-highlight:java">
@Override
public Print createPrint(PageNumber arg0) {
    DefaultGridLook dgl = new DefaultGridLook(0, 3);
    GridPrint gp = new GridPrint(&quot;p, C:D:GROW&quot;, dgl);
    FontData fd = Display.getDefault().getSystemFont().getFontData()[0];
    fd.height = 14;
    fd.setStyle(SWT.BOLD);

    if (_handler.getActivePrintLogo() != null) {
        gp.add(new ImagePrint(_handler.getActivePrintLogo().getImageData(), Display.getDefault().getDPI()));
        gp.add(new TextPrint(&quot;&quot;));
        gp.add(SWT.CENTER, new TextPrint(_title, fd, SWT.CENTER), GridPrint.REMAINDER);
    }

    return gp;
}
</pre>
</pre>
<p>In this code we create a new &#8220;Grid Look and Feel&#8221; (this is a PaperClips class that simply draws borders around cells etc). Then we create a very simple GridPrint that has 2 columns. The first is in a <b>p</b>referred size as we don&#8217;t know the size of the image that will go there (there might be no image even). The second takes up all available space and is centered so that the text shows the title of the document in the middle, but we push it down a row to make it truly centered or the size of the image would push it off.</p>
<h2><b>Previewing the Print</b></h2>
<p>Once we have our PagePrint all set up it&#8217;s finally time to print! PaperClips has a &#8220;ui&#8221; package that contains a PrintPreview dialog. In the downloadable code you will find that this class has been wrapped as I wanted button images in the dialog to be customizable. To show our print preview dialog we call:</p>
<pre>
<pre class="syntax-highlight:java">
PrintPreviewDialog ppd = new PrintPreviewDialog(pp, parentShell, _printHandler);
ppd.open();
</pre>
</pre>
<p>(The PrintHandler is an interface that lets us define what images we use etc)</p>
<p>The result is more or less the following (when fully zoomed out):</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2009/09/pp2.gif"><img src="http://hexapixel.com/wp-content/uploads/2009/09/pp22.gif" alt="Zoomed Out Picture" title="Zoomed Out" width="659" height="599"  /></a></p>
<p>And when zoomed in a bit:</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2009/09/pp3.gif"><img src="http://hexapixel.com/wp-content/uploads/2009/09/pp3.gif" alt="Zoomed In Picture" title="Zoomed In" /></a></p>
<p>Do note that even if the preview may not be 100% perfect look-wise (pixelated etc), the printed version will come out fine. </p>
<h2><b>Conclusions</b></h2>
<p>With PaperClips you can go from zero print-functionality in your application to some pretty fancy reports in just a few hours of work. That&#8217;s its #1 strength and it&#8217;s a very strong argument for using PaperClips. Sure, you can create very fancy reports using <a href="http://www.eclipse.org/birt/phoenix/" target="_new">Eclipse BIRT</a> or <a href="http://www.jaspersoft.com/jasperreports" target="_new">JasperReports</a> (which has sadly gone mostly commercial). For &#8220;normal printing&#8221; however, there&#8217;s no reason to dig into a big reporting engine, just stick to PaperClips!</p>
<h2><b>Download The Code</b></h2>
<p>The code for this article is an Eclipse Project that contains everything necessary to run what you have seen in this Article (you may need to adjust the SWT-jar import paths). It may seem like there&#8217;s a lot of code but in reality it&#8217;s mostly some extra interfaces to make things customizable. That way it&#8217;s not just article code, but code you can actually use. That&#8217;s how I prefer to write articles. Most people want as much customization as possible, and for those that don&#8217;t, they can take out the parts that they need.</p>
<p><a href="http://hexapixel.com/wp-content/uploads/2009/09/com.hexapixel.articles.paperclips.zip">Download Code</a></p>
<p>Happy printing!</p>
<p>(PaperClips version 1.0.4 was used in this article).</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/09/18/printing-swt-tables-with-paperclips/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a Notification Popup Widget</title>
		<link>http://hexapixel.com/2009/06/30/creating-a-notification-popup-widget</link>
		<comments>http://hexapixel.com/2009/06/30/creating-a-notification-popup-widget#comments</comments>
		<pubDate>Tue, 30 Jun 2009 12:00:24 +0000</pubDate>
		<dc:creator>Emil</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Eclipse Articles]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://hexapixel.com/?p=760</guid>
		<description><![CDATA[In this article I will explain how to create a custom widget that displays a popup notification dialog in the bottom right corner of your screen (usually above the toolbar on Windows). Here&#8217;s what it will look like when we&#8217;re done: We could custom draw everything which would allow us more control over the widget, [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I will explain how to create a custom widget that displays a popup notification dialog in the bottom right corner of your screen (usually above the toolbar on Windows). Here&#8217;s what it will look like when we&#8217;re done:</p>
<p><img src="http://hexapixel.com/wp-content/uploads/2009/06/tray_popup_example.gif" alt="Example Image" title="Example Image" width="397" height="147" /></p>
<p>We could custom draw everything which would allow us more control over the widget, but for the sake of this article lets stick to using basic SWT components inside a normal Shell that we will make a bit prettier than your typical SWT Shell.</p>
<p>(Do note this has only been tested on Windows, it&#8217;s quite possible tweaks are necessary for other platforms).</p>
<p><span id="more-760"></span><br />
<h3>The Shell</h3>
<p>What we want is a Shell that stays on top of our application (but not on top of all applications) and doesn&#8217;t steal the active focus or else it would show up in your task manager or move focus away from where the user is now. We also don&#8217;t any normal Shell &#8220;trim&#8221; borders, we&#8217;ll draw our own. Creating it is easy as all of our requirements are available via SWT flags. Thus we can create the Shell as follows:
<pre class="java" name="code">
<pre class="syntax-highlight:java">
_shell = new Shell(Display.getDefault().getActiveShell(), SWT.NO_FOCUS | SWT.NO_TRIM);
</pre>
</pre>
<p>As we have SWT widgets inside our shell and we intend to use a gradient background on the shell itself, all the widgets need to be transparent. This is done by setting the Background Mode on the shell to <code>SWT.INHERIT_DEFAULT</code>. This tells the widgets to inherit the background of their parents, and gives us what we want. So after we create the shell we simply call;
<pre class="java" name="code">
<pre class="syntax-highlight:java">
_shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
</pre>
</pre>
<p>So how do we get a gradient background on a shell? It certainly don&#8217;t support it by default. You can set a foreground and a background but that&#8217;s about it. The trick is to paint an image with the colors we want and use that as the shell&#8217;s background. To set it at the right time, we listen to the <code>SWT.Resize</code> event on the shell and do it then with the following code;</p>
<pre class="java" name="code">
<pre class="syntax-highlight:java">
_shell.addListener(SWT.Resize, new Listener() {
    @Override
    public void handleEvent(Event e) {
	try {
	    // get the size of the drawing area
	    Rectangle rect = _shell.getClientArea();
	    // create a new image with that size
	    Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);
	    // create a GC object we can use to draw with
	    GC gc = new GC(newImage);

	    // fill background
	    gc.setForeground(_bgFgGradient);
	    gc.setBackground(_bgBgGradient);
	    gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);

	    // draw shell edge
	    gc.setLineWidth(2);
	    gc.setForeground(_borderColor);
	    gc.drawRectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2);
	    // remember to dipose the GC object!
	    gc.dispose();

	    // now set the background image on the shell
	    _shell.setBackgroundImage(newImage);

	    // remember/dispose old used iamge
	    if (_oldImage != null) {
		_oldImage.dispose();
	    }
	    _oldImage = newImage;
	}
	catch (Exception err) {
	    err.printStackTrace();
	}
    }
});
</pre>
</pre>
<h3>The Contents</h3>
<p>Our shell consists of 3 sections, an image at the top left (which is a normal CLabel). Then a label that contains the header text (also a CLabel), and finally a label which represents our message (a normal Label). We use a Label at the end instead of a CLabel as Labels support wrapping and multi-lines better than the CLabel does. You could of course use pretty much any widgets you want. Here&#8217;s an outline of what section each label covers:</p>
<p><img src="http://hexapixel.com/wp-content/uploads/2009/06/tray_popup_example_lines.gif" alt="tray_popup_example_lines" title="tray_popup_example_lines" width="350" height="99" /></p>
<p>We use a GridLayout with some 5px margins (except at the top) and the widgets are created normally without any special magic, so I won&#8217;t show that code here (it&#8217;s all at the bottom for you to download). </p>
<h3>Some Eye Candy &#8211; Fading</h3>
<p>Shells support alpha values as of SWT 3.4, so we&#8217;ll use this to make our &#8220;appearing&#8221; and &#8220;disappearing&#8221; a bit prettier. All we need to do to make a shell fade in and out is to have a thread that loops and increases/decreases the alpha channel value for the shell. As we need to be on the Display thread to do this it&#8217;s easiest to do it all via a runnable that we let the Display object run for us at a given interval. </p>
<p>We need to remember to continuously check to see if the shell is disposed as it can happen when we&#8217;re on a thread. When we&#8217;re finished fading in, we want the shell to stay visible for a certain amount of time, and then we want to fade out. So basically the chain is this:</p>
<ul>
<li>Create shell</li>
<li>Fade in shell</li>
<li>Stay visible for X seconds</li>
<li>Fade out shell</li>
<li>Dispose shell</li>
</ul>
<p>All these timers are more or less similar in terms of how the code looks, so I&#8217;ll show one example here and for the rest you can look at the complete source downloadable below. We have some global variables here that should be explained. </p>
<ul>
<li><code>FADE_IN_STEP</code> is how much we increase the alpha value for each iteration.</li>
<li><code>FINAL_ALPHA</code> is a value that declares what the final alpha value will be for the shell when it stays visible. I find that a slightly transparent shell gives a better effect, so by default this value is 225 (out of 255 which is a solid [opaque] shell).</li>
<li><code>FADE_TIMER</code> is how long we wait until increasing the Alpha value again. When the shell has reached it&#8217;s max-alpha value we call the startTimer() method, which is a thread that sleeps for a certain number of seconds before calling the fadeOut() method.</li>
</ul>
<pre class="java" name="code">
<pre class="syntax-highlight:java">
private static void fadeIn(final Shell _shell) {
    Runnable run = new Runnable() {

        @Override
        public void run() {
            try {
                if (_shell == null || _shell.isDisposed()) { return; }

                int cur = _shell.getAlpha();
                cur += FADE_IN_STEP;

                if (cur &gt; FINAL_ALPHA) {
                    _shell.setAlpha(FINAL_ALPHA);
                    startTimer(_shell);
                    return;
                }

                _shell.setAlpha(cur);
                Display.getDefault().timerExec(FADE_TIMER, this);
            }
            catch (Exception err) {
                err.printStackTrace();
            }
        }

    };
    Display.getDefault().timerExec(FADE_TIMER, run);
}
</pre>
</pre>
<h3>Stacked Notifications</h3>
<p>There&#8217;s one last thing we want to support, which is stacked notifications. Assume our notification shell&#8217;s entire life-span is about 5 seconds, what if we have another notify call before the first one has finished showing? We could dispose the first shell and replace it with the new one of course, but a much prettier approach is to simply move the previous shell up, and show the new notification below it. The effect of this is something like this (this screenshot was taken just as the old shells started to fade out, hence the higher alpha on them):</p>
<p><img src="http://hexapixel.com/wp-content/uploads/2009/06/tray_stacked.gif" alt="tray_stacked" title="tray_stacked" width="362" height="431" /></p>
<p>What we do to achieve this effect is rather simple. Every time a notification shell is opened, we keep a reference of it in a static array of shells. When it&#8217;s faded out (and disposed), it&#8217;s removed from the list. Thus, when a new shell is created we simply check to see what&#8217;s already in the array and then set the location for each old shell in the array to <code>-heightOfNewNotificationShell</code> (so to speak). Thus, the old shells move up to make room, but continue their fade-in/fade-out cycles just like before. </p>
<h3>Further Improvements</h3>
<p>Everything could be made prettier than it already is of course, perhaps you want an &#8220;X&#8221; close button, or different colored text, or rounded shell corners. None of that is in the current code, but the code should give you enough to go on to implement most of that without any major problems. </p>
<p>Also note that I currently use <code>Display.getDefault().getActiveShell()</code> for the parent shell of the popup. You may want to refactor it to use a more permanent shell as otherwise a disposal of whatever the parent shell was whenever the popup was displayed will cause the notification to dispose as well.</p>
<p>The code is not perfect, it&#8217;s an example to build on (if you so wish).</p>
<h3>Download Code</h3>
<p>I&#8217;ve created an Eclipse project with the code and also the ImageCache/FontCache/ColorCache classes I use in the code (all they do is keep already used images etc in memory so that they don&#8217;t need to be re-created). There&#8217;s also a jar with the images I&#8217;ve used in this example. If you like them and want more like it, there&#8217;s a massive image pack with exactly these icons and more here: <a href="http://code.google.com/p/gnome-colors/" target="_new">Gnome Colors Icons</a>.</p>
<p>Do note you may need to adjust your CLASSPATH settings for the project to reflect the location of your SWT jars.</p>
<p>To run the code, simply run the <code>Tester.java</code> class and push the big button to create a notification. Push it again before the first one fades away to see the stacking. A random image will be used every time you push it.</p>
<p><a href='http://hexapixel.com/wp-content/uploads/2009/06/notification_widget.zip'>DOWNLOAD CODE</a></p>
<h3>Conclusion</h3>
<p>Hopefully this gives you an insight into how to create a &#8220;custom widget&#8221; (without much custom painting). Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://hexapixel.com/2009/06/30/creating-a-notification-popup-widget/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<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>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>25</slash:comments>
		</item>
	</channel>
</rss>

