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.

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.

Permalink

Do you know that drag and drop from iTunes to a Java Application is broken on Mac OS X? It's not possible because there are no DataFlavors in the Transferable object. On Windows it works!

Best regards,
Tobi

Hi Alvin, thanks for the informative post. However, the ApplicationAdapter interface has been deprecated in favour of handling the com.apple.eawt.events.OpenFilesEvent using a OpenFilesHandler.

I tried to implement a basic image viewer app in JavaFX using both the API's, however neither the OpenFilesEvent or ApplicationEvent as implemented by you, seem to be triggered.
I am working on OS X 10.11 with Java 8 u 73. Have you ever encountered this problem. I am not using jarbundler, but JavaFX Ant tasks for bundling the app as a self contained package. In the info.plist of the app bundle, there are appropriate entries for document type and associated file extensions.

On double clicking a jpeg file or dragging it onto the dock icon of my app, it just brings the app to front and does not file any event for file opening.

Hi Maneesh,

I’m sorry, I haven’t worked with this in a while, and I don’t know the proper way to handle it. If I remember right I tried to update my app late last year with the newer API, and got the same results you did.

I recommend putting a post out on the Mac/Java mailing list. People there have always been very helpful to me.

Best wishes,
Al

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.