Is this the future of the enterprise applications?
Now here is a very elegant enterprise application made by frog design for Lawson Software (click for original size). Something to look forward to in the next releases of Substance?
Now here is a very elegant enterprise application made by frog design for Lawson Software (click for original size). Something to look forward to in the next releases of Substance?
Following the last few entries on using SWT for native text rendering in Swing applications under the Substance look-and-feel, i was contacted by Steve Northover (technical lead of the SWT project) with a few suggestions. First, to recap the relevant entries up until now:
Steve’s first suggestion was to go over the code and make sure that all SWT resources are properly disposed. While this has been considered as one of SWT’s weaker points (something along the lines of “it’s Java, why do i need to explicitly dispose resources”), this is hardly any different from Graphics2D.dispose or even explicitly closing DB connections, streams, files etc in usual Java programs.
If you don’t call the dispose() method of all allocated SWT resources, you can run into the “No more handles” error. While usually it takes quite a while to get there, the native text rasterizer would encounter it fairly quickly (about 5-6 resources are allocated for each text painting in the current implementation). While the text rasterizer itself is disposing all its resources, the test applications did not. This has now been fixed.
The second suggestion was to strip away unnecessary classes from the SWT jar. While this jar is by no means huge (clocking in at about 1.3MB), some people would cringe at this figure. First, i would like to enumerate the reasons why i don’t recommend stripping away the contents of swt.jar (as detailed below):
Having said that, it is possible to strip the swt.jar to as little as 430KB. There are two ways to do so – the approach recommended by Steve, and the aggressive approach that resulted in the current swt-win-stripped.jar available from the CVS repository.
The recommended approach is to work on the package level, removing those packages that clearly are not required for the text rendering. The minimum set according to Steve is org.eclipse.swt.graphics, org.eclipse.swt.widgets, org.eclipse.swt.internal, org.eclipse.swt.internal.win32 and org.eclipse.swt.internal.gdip (for GDI+ operations such as tranformations for the vertical texts). In addition, the swt-win32 and swt-win32-gdip DLLs (for Windows) need to be in the stripped jar. Furthermore, Steve mentions that the org.eclipse.swt.events and org.eclipse.swt.accessibility might be needed for corner-case scenarios, such as switching the OS theme while the program is running (correction from Steve – these are needed to compile a stripped SWT jar from sources).
However, you can take it a little bit further and remove additional classes from the org.eclipse.swt.widgets (pretty much everything that concerns actual components, since these are not needed for the text painting and image manipulation for this plugin). Take a look at the contents of this package in swt-win-stripped.jar in the CVS or the distribution zip to see what has been left. This is what brings the jar size down to 430KB.
As an “extreme” measure, one can go even further and start stripping unnecessary functionality from the DLLs, org.eclipse.swt.SWT class and org.eclipse.swt.internal.win32.OS class. Do at your own risk.
Note that while this entry talks about the Windows version of SWT, the same applies to other platforms as well (which would have a different structure of org.eclipse.swt.internal package and different bundled native libraries).
I’d like to thank Steve Northover for his comments and time.
Here are some Swing links that you might have missed during this week:
Sometimes, the application design requires displaying vertical (rotated) texts. While this is not a common requirement, and the usage of vertical texts must be kept to an absolute minimum, one should be aware of the possible technical solutions and the problems associated with them. This entry shows two possible solutions, accompanied by the screenshots and short technical explanations specific to LCD monitors with enabled subpixel anti-aliasing.
One way to draw rotated texts (by either 90 or 270 degrees) is to draw a horizontal text on an offscreen image, rotate that image by the relevant amount and draw it on the screen. Here is how it looks like (using the native text rendering provided by SWT):
If the texts look a little fuzzy, it’s not because your monitor has different subpixel settings. Here is a 400% zoom on one text:
What’s with the extra horizontal bluish lines? Those come from the original subpixel rendering of the horizontal text that takes advantage of the LCD physical structure, as explained and illustrated in this java.net article by Chet Haase. Unfortunately, this doesn’t work so well on image rotation – the”extra” blue pixels simply make the text fuzzy and much less readable.
What’s the alternative? Another way is to install an affine transformation on the graphic context that rotates all graphic operations by 90 or 270 degrees. The implementation here is a little bit more complicated, since the transformation needs to be preceded by matching offset translation. And here is how it looks like:
Zooming a little on one of the texts:
Now this is crisper than the first technique, it still is far from perfect. For comparison, here is the same exact text drawn unrotated:
Note the width of digit 0 – when it’s drawn horizontally, it has three pixels between the outer sides. However, when it’s drawn vertically, it has only two pixels. Looking back at the screenshot of vertical sliders, the labels look much less defined as compared to the usual Vista texts (under Segoe UI font).
I’m not really sure what causes the loss of pixel in digit 0. During the past few months working with Vista, i have to say that i never have seen a single native application (including Office 2007 and SWT-based Eclipse) using vertical texts anywhere in the UI. Perhaps the native font rasterizer was never optimized to handle this case at all…