Since this article was written in 2008, all the functionality discussed below has been exposed as officially supported public APIs. See the conversion table at the end of this documentation page for full information.
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:

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:

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:

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

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!
The Java desktop team at Sun has not been very active in the blogosphere as of late, providing only a few hints of what will be added to the 6.0 update N. The biggest pieces available so far in the (not so) weekly drops were the Nimbus look-and-feel and Direct3D-accelerated pipeline for Windows. Not much else has been officially confirmed, with hints being dropped on media support and importing artwork from Adobe tools.
Sun has put a significant amount of effort into open-sourcing the JDK (OpenJDK project) and proclaiming that anybody can chip in and contribute to the project. Sadly, the current state of affairs is not quite so close to what the marketing / evangelizing would lead you to believe. One of the biggest obstacles for the community is the planning / scoping process for both 6.0 update N (which is not part of OpenJDK if i understand correctly) and 7.0. Sure, one can always pick the low-hanging fruit from the bug parade, but what about people who want to work on new features (in JDK in general and in desktop in particular)? Why would anyone want to start working on adding a new feature in his private Mercurial forest (or whatever it’s called) when he can’t be sure that the same feature is not being worked on by the core team?
This brings me to pretty much the only “peephole” into what is going on during the development cycle – the much-maligned bug parade. Thanks to the comments on Ben’s blog entry, i’ve found two quite interesting entries:
6656651 – The Java 2D LCD glyph rasterisation is not the same as that of the customer Cleartype rasteriser. Some of the resulting differences are observable on Vista and XP in applications which utilise the Windows L&F. [Evaluation] This can be fixed by asking GDI to perform the rasterisation of glyphs, then caching these glyphs in the same way as now. This avoids disruption to the various 2D rendering pipelines, particularly its hardware acceleration architecture. This has been verified with software and D3D and OpenGL pipelines, and with SwingSet and Font2DTest. […]
6655001 -When window translucency is enabled for windows with accelerated surfaces the tranlucency doesn’t work well on Windows systems prior to Windows Vista: there are artifacts when a window is dragged away, and it doesn’t appear transparent. Shaped windows work fine. […]
Am i dreaming? Is the first one talking about native font rasterization? Is the second one talking about shaped and translucent top-level windows? Now if only 6633275 hasn’t been marked as private (transparency, transparency, transparency)…
I had only two things on my Java desktop wishlist for 2008 – cross-platform support for H.264 / FLV formats and converters / viewers for competing markup formats. To quote myself on the second wish
You know what i’m talking about – those pesky competitors that have 99.9% percent of the consumer-facing rich desktop market. Flash / SWF, Flex / MXML and WPF / XAML. Each has its own set of designer tools for creating rich content. Each has armies of professional designers versatile in using those tools, in addition to Photoshop, Maya and others. Do you really expect them to master yet another (unproven) designer tool?
If JavaFX wants to have a fighting chance, it needs to provide a simple migration path. A path that allows taking an existing Flex / Silverlight application and importing it to JavaFX (at least the visuals).
Is it possible that this is becoming a reality? Here is what James Gosling said to Register Developer during the Mobile & Embedded developer day:
We are putting a lot of effort into interoperability with the Adobe tools – a lot of the Adobe tools are wired into the neurons of the artists of the world, […] We are not trying to be a completely isolated island that has all the tools for everybody.
Obviously, this is completely open to interpretation and speculation, and we’ll have to wait for the grand announcement(s) at this year’s JavaOne. My read on this is that Sun will provide a set of plugins to Adobe tools that will allow exporting art as JavaFX and SceneGraph code. And instead of focusing on creating visual tools for the designers, Sun will put the effort in the programmer’s half of the tool chain.
Only time will tell…
Today I am thrilled to have the first guest spot blogger on “Pushing Pixels”. Christopher Deckers, the developer of DJ project that brings rich native features to Swing applications, has graciously agreed to post a summary of his findings on using the DISPOSE_ON_CLOSE window close mode in WebStart environment. Note that a similar scenario was reported and fixed on another “rogue” VM thread.
After hours of coding, you finally release your wonderful Swing application. It is using Java 1.4 (or later), it was tested locally and it was terminating properly. You package it and release it as a Webstart application. Unfortunately, you are using setDefaultCloseOperation(DISPOSE_ON_CLOSE) on your JFrames. Soon, users complain that your application remains in memory after they hit the close button of the last frame.To track down this abnormal behavior, you read the AWT threading rules again, detailed in the following file from the javadoc:
“Prior to 1.4, the helper threads were never terminated.Starting with 1.4, the behavior has changed as a result of the fix for 4030718. With the current implementation, AWT terminates all its helper threads allowing the application to exit cleanly when the following three conditions are true:
* There are no displayable AWT or Swing components.
* There are no native events in the native event queue.
* There are no AWT events in java EventQueues.”
It sounds like you are respecting the rules, so something somewhere is misbehaving. The culprit seems to be Webstart.
The JVM should exit, which means there is a non-daemon thread alive in the system:
- The non-daemon thread is a Webstart-related system thread.
- The non-daemon thread is the event queue.
Creating a simple test case (an empty JFrame using DISPOSE_ON_CLOSE), we add a timer to dump all the threads a few seconds after we actually close the application.
Comparing a local run and a Webstart run, we see several additional threads in the latter case:
Javaws Secure Thread (non-daemon)
traceMsgQueueThread (daemon)
Image Fetcher 0 (daemon)
CacheCleanUpThread (daemon)
AWT-EventQueue-1 (non-daemon)
TimerQueue (daemon)
TimerQueue (daemon)
Surprisingly, we can see two UI threads (AWT-EventQueue-1 in addition to AWT-EventQueue-0) and a special Webstart thread named “Javaws Secure Thread“.
A quick test shows that if we forcibly kill the “Javaws Secure Thread” (using the not-so-recommended call to Thread.stop()), then closing the application succeeds.
This behavior leads to two conclusions: this Webstart thread is a non-daemon thread so the JVM cannot exit, and it also seems to post new events to the UI thread that restarts it.
Time to hunt for the code of the “Javaws Secure Thread“!
A quick search in jre\lib\javaws.jar and we can find its declaration: a class named SecureThread, nested in the com.sun.javaws.ui.JavawsSysRun class (the code can be found in deploy\src\javaws\share\classes\com\sun\javaws\ui folder of the JDK source distribution).
The code after simplification is roughly equivalent to the following:
class SecureThread extends Thread {
public void run() {
while(true) {
doWork();
}
}
public void doWork() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// stuff
}
}
// other stuff
}
}
All seems confirmed: Webstart does create a non-daemon thread, which continuously posts events to the UI thread.
The solution? Well, like back in the 1.3 days, use EXIT_ON_CLOSE on the main frame (if any) until this eventually gets fixed in webstart.