February 27th, 2008

Translucent and shaped windows in core Java

I first spotted it about a month ago, and today’s build 12 of JDK 6.0u10 delivers on the promise – translucent and shaped windows with core Java classes only!

So, what do you do? First, head over to the JDK6 space at java.net and install 6u10 build 12. After that, you need to point to that install from your project (either IDE or a build script). As Richard mentioned in his Javaposse’s spot, Sun couldn’t publish the relevant APIs in a java.* or javax.* package since officially 6u10 is still not considered a major release. So, the APIs are in com.sun.awt.AWTUtilities. Of course, this may change its place (like Nimbus did), but you can at least start exploring it.

There are a few public static methods in this class, and since the signatures are self-explanatory, you don’t really need the source code. For starters, the inner Translucency enum has three values:

  • PERPIXEL_TRANSPARENT – ability to create a shaped window
  • TRANSLUCENT – ability to create a translucent window
  • PERPIXEL_TRANSLUCENT – ability to create a translucent shaped window

To test support for a specific translucency mode, use AWTUtilities.isTranslucencySupported(Translucency) API. To test whether the specific GraphicsConfiguration supports translucency, use AWTUtilities.isTranslucencyCapable(GraphicsConfiguration) API. This Java class is a simple test utility that illustrates the usage of these two methods. Best thing – even on my Windows 2003 server machine these APIs return true!

Once you know that a specific translucency mode is supported, it’s time to create a shaped and / or translucent window. Let’s start with a simple frame with a few controls (Simple window – java class). Here is how it looks like, with a button, a check box, a radio button and a progress bar:

Simple window screenshot

Let’s make it shaped (Shaped window – java class). For this, we use AWTUtilities.setWindowShape(Window, Shape). It’s hard to say without seeing the code, but the window has to be undecorated – call JFrame.setDefaultLookAndFeelDecorated(true). Otherwise the window is shown in usual rectangular shape. It would be nice to have a boolean return value that indicates a success of the operation. Here is how our window looks now:

Shaped window screenshot

Let’s make a translucent window (Translucent window – Java class). For this, we use AWTUtilities.setWindowOpacityWindow, float). As you can see, the translucency factor is global, and (at least for now) you can not control translucency of each pixel. Here is how our window looks like with 50% opacity:

Translucent window screenshot

And you can combine both calls to have a translucent and shaped window (Translucent shaped window – Java class):

Translucent shaped window screenshot

There are a few other additional public methods in AWTUtilities:

  • getWindowOpacity(Window)
  • getWindowShape(Window)
  • setWindowOpaque(Window, boolean)
  • isWindowOpaque(Window)

I think that the only two things that i’m missing is the per-pixel translucency support and soft-clipping of shaped windows (this would depend on the first item).

Congratulations to the AWT team for making this happen!