javadrag-and-dropawtnetbeans-platform

How to enable java.awt.dnd drop for NetBeans Visual Library Scene?


I have created simple component palette using JLabel with ImageIcon. That's the code of the palette item:

public class TransferableIcon extends JLabel implements Transferable {

  private final Image icon;

  public TransferableIcon(Image image) {
    super(new ImageIcon(image));

    this.icon = image;

    setTransferHandler(ImageTransferHandler.getTransferHandler());
    addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        JComponent component = (JComponent)e.getSource();
        getTransferHandler().exportAsDrag(component, e, TransferHandler.COPY);
      }
    });
  }

  private static final DataFlavor[] FLAVORS = new DataFlavor[]{ DataFlavor.imageFlavor };

  @Override
  public DataFlavor[] getTransferDataFlavors() {
    return FLAVORS;
  }

  @Override
  public boolean isDataFlavorSupported(DataFlavor flavor) {
    boolean result = false;

    for(DataFlavor dataFlavor : FLAVORS) {
      if(dataFlavor.equals(flavor))
        result = true;
    }

    return result;
  }

  @Override
  public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
    if(!isDataFlavorSupported(flavor))
      throw new UnsupportedFlavorException(flavor);
    else
      return icon;
  }
}

My own TransferHandler class overrides some methods:

public class ImageTransferHandler extends TransferHandler {
  private static final TransferHandler TRANSFER_HANDLER = new ImageTransferHandler();

  @Override
  public int getSourceActions(JComponent c) {
    return TransferHandler.COPY;
  }

  @Override
  protected Transferable createTransferable(JComponent c) {
    Image image = null;

    if(c instanceof JLabel) {
      JLabel label = (JLabel)c;
      Icon icon = label.getIcon();
      image = ((ImageIcon)icon).getImage();

      return new TransferableIcon(image);
    }
    else
      throw new IllegalArgumentException("Can not transfer such a widget");
  }

  public static TransferHandler getTransferHandler() {
    return TRANSFER_HANDLER;
  }
}

I have a Visual Library scene, added to JFrame through the scene.createView() method. I added an AcceptAction to scene, created my own AcceptProvider, but it's accept() method is never called: when I try to drag the TransferableIcon to the scene, I see the "not allowed" cursor and nothing happens when I drop the icon to scene. So, how can I enable the drop to the Scene?


Solution

  • The problem was not so complicated as I thought it was. In the AcceptAction class we see, that it accepts drag (and drop as well) with COPY_OR_MOVE action only. So in your own TransferHandler class you must set the exact same action:

    @Override
    public int getSourceActions(JComponent c) {
      return TransferHandler.COPY_OR_MOVE;
    }
    

    And that's it!