Friday, April 16, 2010

SWT Table Images And Transparency

I recently came across a Windows platform issue using images inside an SWT table. A little research turned up this long-standing open SWT bug.

The problem results when you change the background color of a row in a table. I like to alternate colors on the rows in my tables, so I create a LabelProvide like this:


private class PortfolioViewLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider {

@Override
public Color getBackground(Object element, int columnIndex) {
return null;
}

public Image getColumnImage(Object obj, int index) {
Image retImage = null;
return retImage;
}

public String getColumnText(Object obj, int index) {
String retVal = "";
return retVal;
}

@Override
public Color getForeground(Object element, int columnIndex) {
return null;
}
}


Of course, you would actually want to return some real values in those methods.

Using a JFace TableViewer allows the table to be decorated with the listener via the setLabelProvider method.

Under Linux, SWT uses GTK native widgets for table. An example of one of my tables looks like this:

Make sure your monitor is set up so you see each row is a different shade--the first row is a deep gray, and the second row is black.

The table looks fine and all of the images ( transparent png files ) are correctly displayed. Now look at the same application on Windows 7.

Notice the images have black backgrounds now which is the background of the table. The transparency mask in the png is ignored--annoying and ugly. Look closely at the circled area to see the problem.

Luckily, with a little help from old posts in that bug and some trial and error, I came up with an easy fix that works for Windows and Linux. Using the same label provider as above, we can get the row color during the SWT.EraseItem event and erase the area with the same color used for the row:


topPortfoliosViewer.getTable().addListener(SWT.EraseItem, new Listener() {
@Override
public void handleEvent(Event event) {
event.gc.setBackground(plp.getBackground(event.item.getData(), event.index));
event.gc.fillRectangle(event.getBounds());
}
});


And the result on Windows 7:

The result is how I want it. The images blend in correctly. I'm not sure what the real problem is here--is it Windows or Eclipse? Either way, the fix works for me, and I can continue on with development.

The Future Of OpenSolaris...Still Unwritten and Uncertain

I've been following the activities of the OpenSolaris project for some time with interest. With the acquisition of Sun by Oracle, it's future is still uncertain. Since my last entry on the subject, I have only played with it a few times inside a virtual machine.

I remember back when I was in college and OS/2 Warp came out. It was so cool and I was immediately converted. Despite the coolness factor, the conversion was short lived. I don't remember my reasoning for abandoning OS/2--maybe it was my introduction to Linux in a computer lab or the lack of OS/2's ability to satisfy my computer needs compared to Windows or Linux. Whatever the reason, I can't help but recall that experience as I now look at and ponder the fate of OpenSolaris.

I don't think OpenSolaris has a large enough community outside of full-time, paid developers to support the operating system's advancement. Sure, there are a few different distributions out there, but these deal primarily with packaging the kernel--not low-level kernel development. As with OS/2 warp, a few cool technologies found in no other operating system (i.e. DTrace and ZFS ) will not be enough to grow the community and keep the system alive. Without a large and fully open community, a code base the size of an operating system needs some major company-backed financing to grow.

Only time will tell the true fate of OpenSolaris. I think some years down the road I'll look back on my OpenSolaris experience and remember the brief experience with a smile and wonder what may have been.