Enjoy 8)
See the javadoc for details, it wont compile as is because JMEDropTargetEvent does not extend EventObject, but you can easily patch JMEDropTargetEvent or comment 2 lines of my code to see how it works without the patch.
package jmetest.awt.swingui.dnd;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.dnd.DnDConstants;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import com.jme.bounding.BoundingSphere;
import com.jme.input.KeyboardLookHandler;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.system.DisplaySystem;
import com.jmex.awt.swingui.JMEDesktopState;
import com.jmex.awt.swingui.dnd.JMEDndException;
import com.jmex.awt.swingui.dnd.JMEDragAndDrop;
import com.jmex.awt.swingui.dnd.JMEDragGestureEvent;
import com.jmex.awt.swingui.dnd.JMEDragGestureListener;
import com.jmex.awt.swingui.dnd.JMEDragSourceEvent;
import com.jmex.awt.swingui.dnd.JMEDragSourceListener;
import com.jmex.awt.swingui.dnd.JMEDropTargetEvent;
import com.jmex.awt.swingui.dnd.JMEDropTargetListener;
import com.jmex.awt.swingui.dnd.JMEMouseDragGestureRecognizer;
import com.jmex.game.StandardGame;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameStateManager;
/**
* clean and simple drag and drop test with gamestates
*
* for making method DndIcon.drop(JMEDropTargetEvent e) work as intended, you have to patch the class
* JMEDropTargetEvent to make it extend java.util.EventObject ,
*
* then add the Source Object in the constructor like this :
*
* JMEDropTargetEvent(Object source, Point point, int action, JMEDragAndDrop dnd ) {
super(source);
...
* and then update JME classes that instantiate JMEDropTargetEvent
*
* if you want to test without the swapping with source icon, comment this code in DndIcon.drop(JMEDropTargetEvent e)
* //DndIcon source = (DndIcon) e.getSource();
//source.setIcon(this.getIcon());
*
* @author Nomis
*
*/
public class TestDnd {
public static void main(String[] args) {
TestDnd test = new TestDnd();
StandardGame game = new StandardGame("DND test");
game.start();
TestDnd.MyGameState ingameState = test.new MyGameState();
GameStateManager.getInstance().attachChild(ingameState);
// always updateRenderState or get funky effects
ingameState.getRootNode().updateRenderState();
// By the way I strongly advise you to comment it to see the funky
// effects it's really fun !
ingameState.setActive(true);
TestDnd.MyHudState hudState = test.new MyHudState();
hudState.setActive(true);
hudState.getRootNode().updateRenderState();
GameStateManager.getInstance().attachChild(hudState);
}
public class MyGameState extends DebugGameState {
private Box box;
private Quaternion rotQuat = new Quaternion();
private float angle = 0;
private Vector3f axis = new Vector3f(1, 1, 0.5f);
public MyGameState() {
// keyboard look handler because the mouse is used for the hud
super(false);
input = new KeyboardLookHandler(DisplaySystem.getDisplaySystem().getRenderer().getCamera(), 15.0f, 0.5f);
this.box = new Box("my box", new Vector3f(0, 0, 0), 2, 2, 2);
box.setModelBound(new BoundingSphere());
box.updateModelBound();
this.getRootNode().attachChild(box);
this.axis.normalizeLocal();
}
@Override
public void update(float tpf) {
super.update(tpf);
// rotating the box to show there is some 3d behind the UI
if (tpf < 1) {
angle = angle + (tpf * 25);
if (angle > 360) {
angle = 0;
}
}
rotQuat.fromAngleNormalAxis(angle * FastMath.DEG_TO_RAD, axis);
box.setLocalRotation(rotQuat);
}
}
public class MyHudState extends JMEDesktopState {
public MyHudState() {
super();
}
protected void buildUI() {
new JMEDragAndDrop(this.getDesktop());
JInternalFrame frame = new JInternalFrame("test", true, true);
frame.setLayout(new GridLayout(4, 4));
Icon icon1 = getResizedIcon("Monkey.jpg");
frame.add(new DndIcon(this, icon1));
Icon icon2 = getResizedIcon("Monkey.png");
frame.add(new DndIcon(this, icon2));
Icon icon3 = getResizedIcon("logo.jpg");
frame.add(new DndIcon(this, icon3));
// few empty icons to let you play
for (int i = 0; i < 13; i++) {
frame.add(new DndIcon(this, null));
}
frame.setSize(64 * 4, 64 * 4);
frame.setLocation(100, 100);
frame.setVisible(true);
this.getDesktop().getJDesktop().add(frame);
MouseInput.get().setCursorVisible(true);
}
private Icon getResizedIcon(String fileName) {
ImageIcon icon = new ImageIcon(this.getClass().getResource("/jmetest/data/images/" + fileName));
icon.setImage(icon.getImage().getScaledInstance(64, 64, 16));
return icon;
}
}
/**
* DndIcon is the drag source and the drop target, so you can easily drag /
* swap icons from different panels
*
* @author Nomis
*
*/
public class DndIcon extends JLabel implements JMEDragGestureListener, JMEDragSourceListener, JMEDropTargetListener {
private static final long serialVersionUID = 1L;
private JMEDragAndDrop dndSupport;
public DndIcon(JMEDesktopState desktopSate, Icon icon) {
this.setIcon(icon);
this.dndSupport = desktopSate.getDesktop().getDragAndDropSupport();
new JMEMouseDragGestureRecognizer(dndSupport, this, DnDConstants.ACTION_COPY_OR_MOVE, this);
this.setBorder(BorderFactory.createLineBorder(Color.black));
}
// drop = swap this icon with event's source component icon
public void drop(JMEDropTargetEvent e) {
TransferableImage t = (TransferableImage) e.getTransferable();
Icon icon = t.getIcon();
if (icon != null) {
// Set current icon to the source
DndIcon source = (DndIcon) e.getSource();
source.setIcon(this.getIcon());
this.setIcon(icon);
}
}
public void dragGestureRecognized(JMEDragGestureEvent dge) {
if (this.getIcon() == null) {
// nothing to transfer
return;
}
TransferableImage transferable = new TransferableImage(this.getIcon());
try {
dndSupport.startDrag(dge, (ImageIcon) this.getIcon(), transferable, this);
} catch (JMEDndException e) {
e.printStackTrace();
}
}
// we don't care for all other events
public void dragDropEnd(JMEDragSourceEvent e) {
}
public void dragEnter(JMEDragSourceEvent e) {
}
public void dragExit(JMEDragSourceEvent e) {
}
public void dragEnter(JMEDropTargetEvent e) {
}
public void dragExit(JMEDropTargetEvent e) {
}
public void dragOver(JMEDropTargetEvent e) {
}
}
}