# Drag and Drop JPanel auf JPanel nach drop erneut verschieben?



## carolin (24. Jul 2010)

Hallo,

ich bin momentan dabei Drag and Drop mit zwei JPanels umzusetzen. D.h. ich habe ein JPanel (mein NodePanel), das sich per drag auf ein anderes JPanel (in diesem Fall MyStartPanel und MyDropPanel) setzen lässt. Ich möchte allerdings, dass sich mein NodePanel danach weiter per drag verschieben lässt (insbesondere wenn es auf mein MyDropPanel gezogen wurde, das ist, falls ihr das Programm startet, das rechte Panel). Hat jemand eine Idee dazu? Danke schonmal.

Hier ist noch der Code.


```
package dnd;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class DndTest extends JFrame {

	private static final long serialVersionUID = 1L;

	private void initGui() {
		JPanel komplett = new JPanel();
		JPanel listPanel = new JPanel();
		listPanel.setSize(100,100);
	
		MyStartPanel starter = new MyStartPanel();
		komplett.add(starter);
		
		MyDropPanel dropper = new MyDropPanel();
		komplett.add(dropper);
		
		this.setVisible(true);
		this.add(komplett);
		
		this.setSize(500, 500);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public static void main(String[] args) {
		new DndTest().initGui();

	}
}
```

MyStartPanel:

```
package dnd;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;

import javax.swing.JPanel;
import javax.swing.plaf.BorderUIResource;

import dnd.MyDropPanel.MyDropPanelDropTargetListener;

public class MyStartPanel extends JPanel {

	public MyStartPanel() {
				super();
		this.setTransferHandler(new DragAndDropTransferHandler());
		this.setDropTarget(new DropTarget(MyStartPanel.this,
				new MyStartPanelDropTargetListener(MyStartPanel.this)));
		
		
		this.setPreferredSize(new Dimension(200, 200));
		this.setBorder(BorderUIResource.LineBorderUIResource
				.createBlackLineBorder());
		this.setVisible(true);

		this.add(new NodePanel("1"));
		this.add(new NodePanel("2"));
		this.add(new NodePanel("3"));
		
	}
	
		class MyStartPanelDropTargetListener implements DropTargetListener {

		MyStartPanel dropPanel;
		
		public MyStartPanelDropTargetListener(MyStartPanel myDropPanel) {
			this.dropPanel = myDropPanel;
		}

		@Override
		public void dragEnter(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			// TODO Auto-generated method stub

		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

		@Override
		public void drop(DropTargetDropEvent e) {
			try {
				Transferable tr = e.getTransferable();
				DataFlavor flav = NodePanel.getNodePanelDataFlavor();
				if (tr.isDataFlavorSupported(flav)) {
					System.out.println("Wir sind drin!");
					e.acceptDrop(DnDConstants.ACTION_MOVE);

					NodePanel data = (NodePanel) tr
							.getTransferData(flav);
					
					Point loc = e.getLocation();

					data.setLocation(loc);		
					dropPanel.add(data);
					e.dropComplete(true);
					dropPanel.updateUI();
					e.getDropTargetContext().dropComplete(true); //TODO wofuer das?
				} else {
					System.err.println ("DataFlavor.stringFlavor is not supported, rejected");
					e.rejectDrop();
				}
			} catch (UnsupportedFlavorException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

	}

}
```

MyDropPanel

```
package dnd;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTarget;

import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.plaf.BorderUIResource;

public class MyDropPanel extends JPanel {

	public MyDropPanel() {
		super();
		this.setTransferHandler(new DragAndDropTransferHandler());
		this.setDropTarget(new DropTarget(MyDropPanel.this,
				new MyDropPanelDropTargetListener(MyDropPanel.this)));

		this.setPreferredSize(new Dimension(200, 200));
		this.setBorder(BorderUIResource.LineBorderUIResource
				.createBlackLineBorder());
		this.setVisible(true);
		this.setLayout(null);
	}

	class MyDropPanelDropTargetListener implements DropTargetListener {

		MyDropPanel dropPanel;
		
		public MyDropPanelDropTargetListener(MyDropPanel myDropPanel) {
			this.dropPanel = myDropPanel;
		}

		@Override
		public void dragEnter(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			// TODO Auto-generated method stub

		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

		@Override
		public void drop(DropTargetDropEvent e) {
			try {
				Transferable tr = e.getTransferable();
				DataFlavor flav = NodePanel.getNodePanelDataFlavor();
				if (tr.isDataFlavorSupported(flav)) {
					System.out.println("Wir sind drin!");
					e.acceptDrop(DnDConstants.ACTION_MOVE);

					NodePanel data = (NodePanel) tr
							.getTransferData(flav);
					
					Point loc = e.getLocation();

					data.setLocation(loc);		
					dropPanel.add(data);
					dropPanel.updateUI();
					e.getDropTargetContext().dropComplete(true); //TODO wofuer das?
				} else {
					System.err.println ("DataFlavor.stringFlavor is not supported, rejected");
					e.rejectDrop();
				}
			} catch (UnsupportedFlavorException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub

		}

	}

}
```

NodePanel

```
/**
 * 
 */
package dnd;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.Serializable;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.TransferHandler;

/**
 * reprasentiert einen knoten in der topology
 * @author Caro
 *
 */
public class NodePanel extends JPanel implements Transferable, Serializable {

	private static final long serialVersionUID = 1L;
	private Dimension dim = new Dimension(25,25);
	
	public static DataFlavor getNodePanelDataFlavor() {
		return DragAndDropTransferHandler.dataFlavor;
	}
	
	public Dimension getNodePanelDimension() {
		return dim;
		
	}
	
	public NodePanel(String name) {
		//aussehen eines nodes
		this.setPreferredSize(dim);
		this.add(new JLabel(name));
		this.setBorder(BorderFactory.createLineBorder(Color.BLACK,1));
		
		//register mousehandler
		this.addMouseListener(new NodeMouseListener());
		//handler
		this.setTransferHandler(new DragAndDropTransferHandler());
		this.setVisible(true);
		
	}

	@Override
	public Object getTransferData(DataFlavor flavor)
			throws UnsupportedFlavorException, IOException {
		if(!flavor.equals(DragAndDropTransferHandler.dataFlavor)) throw new UnsupportedFlavorException(flavor);
		return this;
	}

	@Override
	public DataFlavor[] getTransferDataFlavors() {
        DataFlavor[] flavors = new DataFlavor[1];
        flavors[0] = DragAndDropTransferHandler.dataFlavor;;
        return flavors;
	}

	@Override
	public boolean isDataFlavorSupported(DataFlavor flavor) {
		return flavor.equals(DragAndDropTransferHandler.dataFlavor);
	}

	/**
	 * 
	 * @author siehe [url=http://www.zetcode.com/tutorials/javaswingtutorial/draganddrop/]Drag and Drop in Swing[/url]
	 *
	 */
	class NodeMouseListener extends MouseAdapter {
		
		public void mousePressed(MouseEvent event) {
			JComponent c = (JComponent) event.getSource();
            TransferHandler handler = c.getTransferHandler();
            handler.exportAsDrag(c, event, TransferHandler.MOVE);
		}
	}

	
}
```

DragAndDropTransferHandler

```
package dnd;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceMotionListener;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.TransferHandler;

public class DragAndDropTransferHandler extends TransferHandler {

	public static DataFlavor dataFlavor;
	
	DragAndDropTransferHandler() {
		super();

		dataFlavor = new DataFlavor(NodePanel.class, "NodePanel");
	}
	

	protected Transferable createTransferable(JComponent c) {
		if (c instanceof NodePanel) {
			Transferable tra = (NodePanel) c;
			return tra;
		}
		return null;		
	}
	
	public int getSourceActions(JComponent c) {
		if(c instanceof NodePanel) {
			return TransferHandler.MOVE;
		}
		return TransferHandler.NONE;
	}

	
}
```

Gruß,
Carolin


----------



## carolin (25. Jul 2010)

Problem gelöst. Ich setze einfach meinen TransferHandler und meinen MouseListener neu.


----------



## keram (26. Okt 2015)

Wo wird der TransferHandler und der MouseListener neu gesetzt?


----------



## keram (28. Okt 2015)

Der Listener und Transferhandler muss im drop event neu gesetzt werden


----------

