Figured it out.
The key is to create a DataFlavor per drop target component. So here I have 4 targets which accept drops of type foo, 3 buttons and 1 panel.
fooCopyButtonFlavor = new DataFlavor(FooCopyButtonTransferData.class, "Foo 'Copy Button' Transfer Data");
fooEditButtonFlavor = new DataFlavor(FooEditButtonTransferData.class, "Foo Entry 'Edit Button' Transfer Data");
fooDeleteButtonFlavor = new DataFlavor(FooDeleteButtonTransferData.class, "Foo Entry 'Delete Button' Transfer Data");
fooDialogPanelFlavor = new DataFlavor(FooDialogPanelTransferData.class, "Foo Entry 'Dialog Panel' Transfer Data")
I decided to wrap up my Foo state class.
And make this wrapper implements a custom interface I named TransferDataStrategy. Doing this now allows me to perform different actions in the importData(...) function for the same flavors.
public interface TransferDataStrategy<MODEL>
{
MODEL getModel();
OptionStrategy getOptionStrategy();
}
My Transferable
implementations (which can be thought of as the SOURCE of the drag) can now drive what happens on drop for the same DataFlavor
(or Drop Target Component) by returning different strategies.
public class SourceOneTransferOperation implements Transferable
{
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
{
if (flavor.equals(FooDataFlavor.fooCopyButtonFlavor)) {
TransferDataStrategy<Foo> tds = new FooCopyAAA(model);
return tds;
}
...
}
}
Notice Source Two Below is also supports FooCopyButtonFlavor, but returns a different strategy.
public class SourceTwoTransferOperation implements Transferable
{
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
{
if (flavor.equals(FooDataFlavor.fooCopyButtonFlavor)) {
TransferDataStrategy<Foo> tds = new FooCopyBBB(model);
return tds;
}
...
}
}
This is quite hard to explain but hopefully it might help.