Skip to main content

Introducing JDesktop Integration Components, Part 1

October 14, 2004


The Desktop Component
The Filetypes Component
The Browser Component
The Packager Component
The System Tray
Incubator Projects
SaverBeans SDK

If you have been a Java developer for a while you may have had the
experience of being told that Java can't do everything that native C can.
You may have struggled with the HMTLEditor pane while Windows developers
down the hall embed Internet Explorer into their programs with just a few
lines of code. I'll admit it: as great as Java is, there are times I long
for the features and system access of native programming. Well, we don't
have to wait any longer.

If you hang out on at all, or read any of the JavaOne news
coverage, you may have heard of the JDesktop Integration Components
(JDIC). This new API lets Java developers finally do the sorts of things
we've always envied of our native brethren. This article will give you a
complete overview of the JDIC features, with a small example of each, and a
list of what to download to get started. We will try out all of the APIs
except for the SaverBeans sub-project, which I will cover separately in part

JDesktop Integration Components, or JDIC, is a catchall project for a
set of modules that gives Java developers access to native features through
cross-platform APIs. It was started by the Desktop group at Sun to let
Java applications better integrate with the desktop on which they are running.
They made JDIC open source to as a way to get rapid feedback from
developers on desired features, as well as bug reports. While there are no current
plans to do so, the JDIC team is looking into pulling some of the JDIC
features into a future version of the core Java libraries.

JDIC is broken up into five components and one incubator project:

  • Desktop: Launches desktop programs to open, edit, print, and mail files.
  • Filetypes: Sets desktop file type associations.
  • Browser: Embeds a native web browser (Internet Explorer or Mozilla) into an AWT canvas.
  • Packager: Command-line tools for converting Java Web Start programs into native installers.
  • Tray API: Support for system tray icons and pop-up menus.
  • SaverBeans: System screensavers in Java

The Desktop Component

The Desktop component is the simplest and possibly most useful of the
JDIC components. Its entire existence is devoted to basic desktop services
like opening a file in the right editor, starting an email message, or
sending a URL to the default web browser. These are all things that require
a lot of work under the hood to build, but very little to use. If you want
to tell the OS to open a Microsoft Word document, then just call File("resume.doc"));. It's that simple.

The org.jdesktop.jdic.desktop package only has three
classes: Desktop, Message, and
DesktopException. The Desktop class is static and cannot be
instantiated. It has methods for opening, editing, and printing files. You
can also open a new email and populate it with text. This is where the
Message class comes in, which lets you set the recipient,
body, attachments, and all of the other email parts.

The best thing about the Desktop components package is how easy it is to use. You
don't have to register any special drivers or change configuration based on
the current platform. That's all done for you under the hood. As long as
the jdic.jar file is in your classpath and the correct native lib is in your
library path (usually you just put it with the .jars) then the code will
simply work. Here is a one-line example to launch a browser:

import org.jdesktop.jdic.desktop.*;

public class DesktopTest {
    public static void main(String[] args)
            throws Exception {
            new URL("")

The Filetypes Component

The next core component of JDIC is the Filetypes package,
which sets file type associations. This means you can tell the operating
system what program to use with what files, such as always opening text
files using Word instead of Notepad. Using this API you can query, set, and
delete file type associations based on file extensions and mime types.

Given that file type associations are usually quite operating-system-specific, this API is more useful for retrieving associations or registering
the application itself rather than for setting associations. For example,
the usual text file association under Windows is to call
notepad.exe in a well-known directory. Under Gnome, it might be
to call /usr/local/bin/gedit. Since this is system-specific it
probably isn't very useful to set associations except to tie a Java
application to its own file types. Still, no matter what you do
with it, the Filetypes component handles all of the heavy lifting for you,
dealing with the registry and MIME-type database.

Here is a short example of setting file associations:

import org.jdesktop.jdic.filetypes.*;
public class FileTypesTest {
    public static void main(String[] args)
        throws Exception {
        Action action = new Action("open",
                 "C:\\WINDOWS\\system32\\notepad.exe %1");
        Association assoc = new Association();
        AssociationService svc = new AssociationService();

The first two lines of the main
method create an Action that will
open the file (represented by %1)
with notepad.exe. The next four lines
create an association between the action and the
.mchat file extension. I threw the
MIME-type in there for good measure. In the past,
most operating systems relied exclusively on the
file extension or proprietary metadata to
determine the file type. These days, however, most
operating systems are moving towards MIME
settings for all file typing, so it's good to
start using them now. The last two lines actually
register the association with the system. As with
all JDIC APIs, as long as the native lib is in
your library path, you don't need to do anything
special to get it to work.

The Browser Component

The third main component of JDIC is the Browser. Unlike the previous
two, which just give you access to system services, this component gives you
a real AWT widget to use in graphical applications. Previously, you could
use third-party embedded components or all-Java browsers (see "HTML Renderer Shootout, Part 1"), but JDIC lets you embed the user's default web
browser inside of your application, opening the door to many possibilities.
Now writing things like RSS readers with full web support becomes possible.
Downloading will also be faster, because you won't have to include the
native browser with your application.

The Browser API gives you access to a few browser events and control
over the history (forward, back, refresh). Future revisions of the API are
expected to provide even more access to the browser and any loaded

Using the browser from your application is really quite easy:

import org.jdesktop.jdic.browser.*;
import javax.swing.*;

public class BrowserTest {
    public static void main(String[] args) throws Exception {
        WebBrowser browser = new WebBrowser();
        browser.setURL(new URL(""));
        JFrame frame = new JFrame("Browser Test");

As you can see, the WebBrowser object is just an AWT component that you
can drop into a standard JFrame. The first line of the main method creates
a new WebBrowser and the second sets the URL you want to show. The
rest of the code creates a frame, adds the browser to it, and makes the
frame visible. Once running, its display looks like Figure 1.

Figure 1. Embedded WebBrowser

Figure 1. Embedded WebBrowser

Remember that the WebBrowser is a native AWT component, so you may run into
issues combining it with Swing. The two rules for mixing them is 1) never
overlap Swing and AWT components, and 2) call
on your menus or they will disappear behind the browser component. See this
Swing Connection article for more on mixing
AWT and Swing.

Right now, the Browser component will use the user's default web browser,
which usually means Internet Explorer or Mozilla, and you can't bundle the
necessary parts of Mozilla with your application like you can with JRex. This behavior is probably okay for
Windows, where IE is pretty much guaranteed to be there, but this will be
more problematic on Linux where, the default browser may not be Mozilla
(it may be Konquorer in KDE, for example). Hopefully these issues will be resolved as
the project matures, but right now it's still quite useful for a variety of

The Packager Component

Unlike the rest of JDIC, the Packager module is not an API. Instead, it
is a set of command-line tools that convert JNLP (Java Web Start)
applications into native installers. (rpms for Linux, pkgs for Solaris, and
msis for Windows). This doesn't mean your application is turned into an .exe
like with JSmooth or JExePack; it simply gives you a
one-click installer for a Web Start application. After the program is
installed, it will update itself over the Internet, use the JNLP descriptor,
and do all of the other things that Web Start applications do.

The Packager component requires J2SE 5.0 and
native tools. For Windows, you will also need to install Microsoft's MSI
SDK. Once your environment is set up, you can use the command-line tools
jnlp2msi, jnlp2rpm, and jnlp2pkg to
convert your Web Start application into a platform-specific installer.

The System Tray

The Tray Icon API used to be an incubator project, but due to the
diligent efforts of the community, it has matured and been promoted
to a full JDIC component status. It's entire purpose is to create
those little program state-icons in the lower-right-hand corner of your
screen, assuming your operating system has a system tray concept. In
practice, this means Windows and Linux. Mac OS X users are out of luck (or
better off, depending on your point of view). It also supports pop-up menus
and automatic tooltips for the icons. Like the rest of JDIC, system-tray
support requires native code, but you can code against a Java API with a
pre-compiled native library.

Since the API is pretty small in scope, there
are only two classes: SystemTray and
TrayIcon. The SystemTray class has a
static factory method for accessing the default
system tray. TrayIcon lets you attach a
JPopupMenu and an Icon
to the next available space on the system tray.
Finally, call
to get your pop-up to appear. Let's examine a small

import org.jdesktop.jdic.tray.*;
import java.awt.event.*;
import javax.swing.*;

public class SystemTrayTest {
    public static JMenuItem quit;
    public SystemTrayTest() {
        JPopupMenu menu = new JPopupMenu("My Menu");
        menu.add(new JMenuItem("Test 1"));
        menu.add(new JMenuItem("Test 2"));
        quit = new JMenuItem("Quit");
        quit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {

        ImageIcon icon = new ImageIcon("duke.gif");
        TrayIcon tray_icon = new TrayIcon(icon, "System Tray Test!", menu);
        SystemTray tray = SystemTray.getDefaultSystemTray();
    public static void main(String[] args) {
        new SystemTrayTest();

In the first few lines of the SystemTrayTest constructor we create a
JPopupMenu with three menu items. The last one, quit, adds an
ActionListener to quit the program. Now, instead of adding the menu to a menu bar or
JComponent, we put the menu into the constructor of a TrayIcon. The
ImageIcon for the system tray image is also passed into the TrayIcon,
along with text for a tooltip. Finally, we add the TrayIcon to the
default SystemTray and the program is done. Compile this with tray.jar
in your classpath and tray.dll in your library path (usually the working
directory). The icon and its menus are shown in Figure 2.

Figure 2. Tray API Example

Figure 2. Tray API Example

The Tray API also supports animated GIF icons and left-click actions. With
this API, you can make your application completely disappear into the taskbar
until needed.

You can download the current binary distribution here, but you should
remember that even as much as the whole JDIC project is still under
development, the Tray API is very alpha. For example, the pop-up menu will
not appear properly if the taskbar is not at the bottom of the screen.-->

Incubator Projects

From the start, JDIC was designed to actively encourage and develop new
APIs. To facilitate project growth they created an incubator project, where
developers can commit code and try out ideas. If they ideas are good enough
and the implementations mature, the project can be promoted to a full JDIC
module or even spun out into its own complete project.

The JDIC team wants more contributors, so please join in. You will have
to sign and fax in the JCA (Joint Copyright Agreement), since parts of JDIC
may eventually be pulled into future versions of Java. They are looking for
cross-platform APIs with native implementations. This means that Java
bindings to Gnome would not be appropriate, since they are specific to Gnome,
but a cross-platform API for drawing non-rectangular windows (my personal
wish) would be very welcome.

SaverBeans SDK

I've saved my favorite API for last. JDIC has one major incubator
project right now: a toolkit to create cross-platform screensavers called
SaverBeans. Like the rest of JDIC, you can code entirely in Java, letting a
pre-built native library handle the messy details. The project consists of
an API for handling callbacks, an XML file for configuration, and an Ant
task that produces the platform-specific screensaver executables
(.scrs for Windows and shell scripts for Unix) with their
support files.

Writing a screensaver is a bit more complicated than using the other
APIs, so I have saved this one for part two of this series. However, if you
want to get started right away, you can download the SDK
and a collection of community-built screensavers.


Though JDIC is still beta, it shows great promise. Changes have been
coming fast and furious as open source developers embrace and extend it.
Work is already under way to fold in older projects, fix the bugs, support
the Mac, and eventually migrate parts of JDIC to the core runtime.

Though it seemed to come out of nowhere, JDIC is something that many
Java developers have been wanting for a long time. Now that it's here, we
can really develop Java applications that do everything native programs do.
I'll see you in a few weeks, when we will convert a particle simulator into
a top-notch screensaver.

Josh Marinacci first tried Java in 1995 at the request of his favorite TA and has never looked back.
Related Topics >> GUI   |   Swing   |