Java, Mac, and the Dock: How to handle drop events to a Mac OS X Dock icon

Note: I originally wrote this article many years ago, and the API I write about has been deprecated and no longer works. Sorry, I don’t know a solution for current versions of Mac OS X and Java (currently Java 8). I’ll update this article when I learn more.

Lately I've been doing a lot of Java programming on Apple's Mac OS X platform, and my most recent effort has been to handle drag and drop events in my Java Swing application. Not satisfied to handle "simple" drag and drop events, I decided I wanted to take my application even farther, and let users drag files and images to my Java application icon in the Mac Dock.

When I started down this road, I didn't know if this could be done, but I'm glad to say it can, and I'm sharing the recipe here. The interesting thing is that I don't think you can do this with Java code alone; my solution involves a combination of Java code and an Ant build process using the JarBundler task that was created just for the OS X platform.

The Java source code

I've stripped my Java source code and my Ant build process down to just the bar essentials, and the first thing I'm going to share here is my Java source code. I've also documented my source code a lot, so I won't add a great deal of description here.

Without any delay, here is a Java program that demonstrates all the programming techniques that are required to make your Java application aware of drag and drop events, in particular to files and images that are dropped to your application icon in the Dock:

package com.devdaily.macdocktest;

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import com.apple.eawt.Application;
import com.apple.eawt.ApplicationAdapter;
import com.apple.eawt.ApplicationEvent;

/**
 * A Java program that demonstrates how to handle the Mac OS X event
 * when a file is dropped onto a Java application's icon in the Dock.
 * This same technique also happens to work for other drag and drop
 * file events on Mac OS X.
 * 
 * @author alvin alexander, devdaily.com.
 * 
 * @see http://devworld.apple.com/documentation/Java/Reference/1.5.0/appledoc/api
 */
public class JavaMacDockTest
{
  JFrame frame;
  
  public static void main(String[] args)
  {
    new JavaMacDockTest();
  }
  
  public JavaMacDockTest()
  {
    // create an instance of the mac osx Application class
    Application theApplication = new Application();
    
    // create an instance of our DockBarAdapter class (see source code below)
    DockBarAdapter dockBarAdapter = new DockBarAdapter(this);

    // add our adapter as a listener on the application object
    theApplication.addApplicationListener(dockBarAdapter);

    // create and display a simple jframe
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        frame = new JFrame("Mac Dock Icon Drag and Drop Test");
        // let the user close the application by pressing the frame's close icon
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(300,200));
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    });
  }
  
  // our "callback" method. this method is called by the DockBarAdapter
  // when a "handleOpenFile" event is received.
  public void handleOpenFileEvent(ApplicationEvent e)
  {
    JOptionPane.showMessageDialog(frame, "Got the file: " + e.getFilename());
  }
  
}

/**
 * Extend the Mac OS X ApplicationAdapter class, and just implement the
 * handleOpenFile() method so we can handle drag and drop events.
 */
class DockBarAdapter extends ApplicationAdapter
{
  private JavaMacDockTest handler;
  
  // the main class passes a reference to itself to us when we are constructed
  public DockBarAdapter(JavaMacDockTest handler)
  {
    this.handler = handler;
  }
  
  // this is the method that is called when a drag and drop event is received
  // by the Application, and passed to us. In turn, we call back to the main
  // class to let it know this event was received so it can deal with the
  // event.
  public void handleOpenFile(ApplicationEvent e)
  {
    handler.handleOpenFileEvent(e);
  }
}

Discussion

The source code has a lot of comments in it, so I won't add too much to it here. I will say that the most important things you can do in regards to working with file drag and drop events is to learn about Apple's Application and ApplicationAdapter classes.

“Treat every moment as your last.
It is not preparation for something else.”
 
~ Shunryu Suzuki

But wait, you need more

As good as that Java code is :), unfortunately it's not enough to handle drag/drop events to the application icon in the Dock. You have to go through a little more work to make your Java application more like a native Mac OS X application, and in Part 2 of this tutorial I'll demonstrate how to make that work.

Continue on to Part 2 of this tutorial where I share the source code for my Ant build script.