X

Geertjan's Blog

  • June 5, 2007

NetBeans DragAndDropHandler Class and the "Enclose In" Feature

Geertjan Wielenga
Product Manager
I received an interesting bit of code from Stan Aubrecht, the NetBeans drag-and-drop king, yesterday. It is an implementation of the NetBeans API org.netbeans.spi.palette.DragAndDropHandler class. It lets you drag a piece of code from the editor into the palette:

private static class MyHandler extends DragAndDropHandler {
public void customize(ExTransferable t, Lookup item) {
}
@Override
public boolean canDrop(Lookup targetCategory, DataFlavor[] flavors, int dndAction) {
for( DataFlavor flavor : flavors ) {
if( DataFlavor.stringFlavor.equals( flavor ) ) {
//some text is being dragged over the palette so let's allow the drop
//(we may want to check that the text is dragged over some specific
//'customizable' category)
return true;
}
}
return super.canDrop(targetCategory, flavors, dndAction);
}
@Override
public boolean doDrop(Lookup targetCategory, Transferable item, int dndAction, int dropIndex) {
if( item.isDataFlavorSupported( DataFlavor.stringFlavor ) ) {
try {
String draggedText = (String)item.getTransferData( DataFlavor.stringFlavor );
//show some add-to-palette dialog window to select item name and icon
//create a new item
//add it to targetCategory
return true;
} catch( IOException e ) {
Exceptions.printStackTrace( e );
} catch( UnsupportedFlavorException e ) {
Exceptions.printStackTrace( e );
}
}
return super.doDrop(targetCategory, item, dndAction, dropIndex);
}
}

To use the DragAndDropHandler, you need to add it as an argument to the PaletteFactory.createPalette method, as shown in the highlighted bit here:

public static PaletteController createPalette() {
try {
if (null == palette)
palette = PaletteFactory.createPalette(JAVA_PALETTE_FOLDER, new MyActions(), null, new MyHandler());
return palette;
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return null;
}

"That's all well and good," you might think, "but, so what?" Well, if you read the code on page 352 and 353 of Rich Client Programming: Plugging into the NetBeans Platform, you'll find a piece of code that programmatically creates an XML file that conforms to the NetBeans Editor Palette Item DTD. If you create that XML file in the appropriate folder in the user directory, it will appear in the palette. So, once the text from the editor is dropped in the palette, you need a small dialog box to appear, where the user can specify the palette item's display name, tooltip, and icons. And then you're done, because the code above handles all the rest. In other words, the code above handles the drag from the editor and the drop in the palette.

One thing I learned was that you need to make sure that the user copies the text from the editor, instead of cutting, otherwise the snippet will be in the palette, but not in the editor (anymore)! That's easy to implement, all you need to do is make sure that the DndAction brings the correct int, as shown in the highlighted condition within the if statement below:

@Override
public boolean canDrop(Lookup targetCategory, DataFlavor[] flavors, int dndAction) {
for( DataFlavor flavor : flavors ) {
if( DataFlavor.stringFlavor.equals( flavor ) && dndAction == 1 ) {
//some text is being dragged over the palette so let's allow the drop
//(we may want to check that the text is dragged over some specific
//'customizable' category)
return true;
}
}
return super.canDrop(targetCategory, flavors, dndAction);
}

So, above, the drop will not succeed unless a copy action is done. A copy action is done when the user holds down the Ctrl key prior to moving the text to the palette. Otherwise, it is a cut action (which returns a "2" instead of a "1" for the DndAction).

Once I have this whole scenario completely worked out, including the icons (which is what I'm working on now), I'll make it available somehow. The combination of MIME-type registration and the new NetBeans Editor Palette Item DTD make this scenario possible. By the way, if you compare what I'm doing here to the scenario outlined in Palette API and 6.0, Testing the Waters... (Part 3)
, then it is interesting to outline the difference. And the difference is that in that scenario, the user had to right-click in the editor and choose a menu item. When the menu item was chosen, the small customizer appeared. In contrast to that, the current scenario uses the DragAndDropHandler class, which enables the text in the editor to be dragged, and thus allows for a smoother experience for the user (i.e., no right-clicking necessary and not necessary to select a menu item, because all you're doing is dragging). That's the only difference. In that scenario, I was using the latest NetBeans Editor Palette Item DTD already, hence I was able to let the user specify their own display name, tooltip, and icons, which wasn't possible in the earlier version of the DTD, since there they had to be defined in a properties file, within the module.

One other interesting thing... today, for the first time, I noticed the feature that I was so happy about at NetBeans Day in San Francisco. In fact, in my report on that day (here), my very first paragraph described the new "enclose in" functionality, allowing me to select components in the GUI Builder and then do a kind of 'surround with' a selected container, such as a JPanel. To see what I mean look at it here:

So, now I just need to select the container and then my selected components are immediately grouped within that container. Extremely handy. Great to have it available for real now.

Join the discussion

Comments ( 3 )
  • Peter Williams Tuesday, June 5, 2007
    If you really want to get fancy about making the palette manager do your bidding, check out the jMaki module (http://ajax.dev.java.net). It supports user definable component libraries for third party jMaki components which are drop target sensitive (distinct snippets based on editor mime type), but no code is required by the library provider -- the palette manipulation code is all in the plugin.
  • Geertjan Wednesday, June 6, 2007
    Thanks for the idea, Peter. I think there's definitely a lot to learn from Ludo's JMaki tooling. I'm going to have a look at it soon, from the inside.
  • Peter Williams Thursday, June 7, 2007
    Just for the record - Ludo wrote the initial DnD code that required a NBM component library. Greg Murray expressed interest in a simple library format so end users could write jMaki component wrappers for their own components and easily install them into the NetBeans Palette. I'm the one who solved that problem and enabled the dynamic component libraries (works in 5.5 too).
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.