# Drag and drop from Tree View to List

**URL:** <https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [October 20, 2022, 5:41pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479 "2022-10-20T17:41:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![prasath.t](https://avatars.discourse-cdn.com/v4/letter/p/898d66/32.png) [@prasath.t](https://forum.inductiveautomation.com/u/prasath.t)\
**Post date:** [October 20, 2022, 5:41pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479/1 "2022-10-20T17:41:51Z")

</div>

Hi, I am trying to drag and drop from tree view to list

example image

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/7/575e597b588098a44caefb0f0042f61d5834fc76.png)

Script i am using in tree view in mouse pressed

```auto
from java.awt.dnd import DragSource,DragGestureListener
from java.awt.dnd import DragSourceListener 
from java.awt.dnd import DnDConstants
from java.awt.datatransfer import Transferable
from java.awt.datatransfer import StringSelection
	
def addDrag(self):	
	class MyDragGestureListener(DragGestureListener):
		def __init__ (self,selectedPath):
			DragGestureListener. __init__ (self)
			
		def dragGestureRecognized(self,DragGestureEvent): 
			transferable = StringSelection("");
			myDragDrop.startDrag(DragGestureEvent, DragSource.DefaultCopyDrop, transferable, myDragSourceListener)
	
	class MyDragSourceListener(DragSourceListener):
		def __init__ (self,selectedPath):
				DragSourceListener. __init__ (self)
		
	class MyDragDrop(DragSource): 
		def __init__ (self,selectedPath):
			DragSource. __init__ (self)
			self.selectedPath = selectedPath
			
	myDragGestureListener = MyDragGestureListener(event.source)
	myDragSourceListener = MyDragSourceListener(event.source)
	myDragDrop = MyDragDrop(event.source)
	myDragDrop.createDefaultDragGestureRecognizer(event.source,DnDConstants.ACTION_COPY_OR_MOVE, myDragGestureListener)

```

example screen shot

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/b/2b7d195e3b0f46018bebbd0d9a4cb5381a416c8b.png)

when i drag i am getting this error

```auto
Exception in thread "AWT-EventQueue-0" java.awt.dnd.InvalidDnDOperationException: Drag and drop in progress
	at java.desktop/sun.awt.dnd.SunDragSourceContextPeer.setDragDropInProgress(Unknown Source)
	at java.desktop/java.awt.dnd.DragSource.startDrag(Unknown Source)
	at java.desktop/java.awt.dnd.DragSource.startDrag(Unknown Source)
	at java.base/jdk.internal.reflect.GeneratedMethodAccessor256.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
	at org.python.core.PyObject. __call__ (PyObject.java:422)
	at org.python.core.PyMethod. __call__ (PyMethod.java:187)
	at org.python.pycode._pyx136.dragGestureRecognized$3(<event:mousePressed>:14)
	at org.python.pycode._pyx136.call_function(<event:mousePressed>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:197)
	at org.python.core.PyFunction. __call__ (PyFunction.java:485)
	at org.python.core.PyMethod.instancemethod ___call__ (PyMethod.java:237)
	at org.python.core.PyMethod. __call__ (PyMethod.java:228)
	at org.python.core.PyMethod. __call__ (PyMethod.java:218)
	at org.python.core.PyMethod. __call__ (PyMethod.java:213)
	at org.python.core.PyObject._jcallexc(PyObject.java:3565)
	at org.python.core.PyObject._jcall(PyObject.java:3598)
	at org.python.proxies. __builtin__ $MyDragGestureListener$58.dragGestureRecognized(Unknown Source)
	at java.desktop/java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(Unknown Source)
	at java.desktop/sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(Unknown Source)
	at com.inductiveautomation.factorypmi.application.components.util.EventDelegateDispatcher$MouseEventDispatcher.mouseDragged(EventDelegateDispatcher.java:145)
	at java.desktop/java.awt.AWTEventMulticaster.mouseDragged(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.mouseDragged(Unknown Source)
	at java.desktop/java.awt.Component.processMouseMotionEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseMotionEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" NotImplementedError: 'MyDragSourceListener' object does not implement abstract method 'dragEnter' from 'java.awt.dnd.DragSourceListener'
Exception in thread "AWT-EventQueue-0" NotImplementedError: 'MyDragSourceListener' object does not implement abstract method 'dragOver' from 'java.awt.dnd.DragSourceListener'
Exception in thread "AWT-EventQueue-0" NotImplementedError: 'MyDragSourceListener' object does not implement abstract method 'dragOver' from 'java.awt.dnd.DragSourceListener'
Exception in thread "AWT-EventQueue-0" NotImplementedError: 'MyDragSourceListener' object does not implement abstract method 'dragOver' from 'java.awt.dnd.DragSourceListener'
Exception in thread "AWT-EventQueue-0" NotImplementedError: 'MyDragSourceListener' object does not implement abstract method 'dragDropEnd' from 'java.awt.dnd.DragSourceListener'

```

can anyone please correct my script please

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 20, 2022, 5:57pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479/2 "2022-10-20T17:57:16Z")

</div>

Consider using `DragSourceAdapter` as your base, instead of `DragSourceListener`

There's also some example code on the forums you can use as a base, if you haven't already found it.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [October 24, 2022, 8:06pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479/3 "2022-10-24T20:06:12Z")

</div>

Okay a little bit of work and understanding, and taking @paul-griffith's tip, and I was able to accomplish this.

This will do multi or single selection, and will handle dragging folders. The drop listener also filters out duplicate paths.

You'll want to add this code to a custom function on your Tree View component that you call from the `InternalFrameActivated` event on the window.

```auto
def addDragSource(self):
	from java.awt.dnd import DragSourceAdapter, DragGestureListener, DragSource, DnDConstants
	from java.awt.datatransfer import DataFlavor, Transferable
	
	#A custom transferable which allows a List to be transfered
	#via Drag and Drop.
	class customTransferable(Transferable):
		_transferData = None
		def __init__ (self,data):
			self._transferData = data
		
		def getTransferData(self,flavor):
			return self._transferData
		
		def getTransferDataFlavors(self):
			return [DataFlavor(list,'List')]
		
		def isDataFlavorSupported(self,flavor):
			if not DataFlavor(list,'List'):
				return False
			return True
	
	#Custom listener to build the transferable when a drag gesture is recognized.
	#Takes in a component (assumes PMITreeView)		
	class customDragGestureListener(DragGestureListener):
		_comp = None
		_selectedPaths = []
		def __init__ (self,comp):
			self._comp = comp
			
		def dragGestureRecognized(self,e):
			dataFlavor = DataFlavor(list,'List')
			
			self.addPaths(self._comp.selectedPaths)
			
			transferable = customTransferable(self._selectedPaths)
			e.startDrag(DragSource.DefaultCopyDrop,transferable)
	
		def addPaths(self,paths):
			for path in paths:
				if not self._comp.separationCharacter in path:
					#this is a root folder, add all sub paths of this folder
					subPaths = [subPath for subPath in self._comp.data.getColumnAsList(0) if path in subPath]
					self.addPaths(subPaths) 
				#if path is found in first columnn then it is a folder.
				#only add paths that aren't in 
				elif path in self._comp.data.getColumnAsList(0):
					#build subPaths list
					subPaths = [row['path'] + '/{}'.format(row['text'])	for row in system.dataset.toPyDataSet(self._comp.data) if row['path'] == path]
					self.addPaths(subPaths)
				elif not path in self._selectedPaths:
					self._selectedPaths.append(path)
				
	
	ds = DragSource.getDefaultDragSource()
	ds.createDefaultDragGestureRecognizer(self, DnDConstants.ACTION_COPY, customDragGestureListener(self))

```

Then add this to the `List` component. You will also need to call this from `InternalFrameActivated`

```python
def addDropTarget(self):
	from java.awt.dnd import DropTargetAdapter, DropTarget
	from java.awt.datatransfer import DataFlavor
	class customDropListener(DropTargetAdapter):
		_comp = None
		def __init__ (self,comp):
			self._comp = comp
		def drop(self,e):
			e.acceptDrop(e.getDropAction())
			self._comp.addData(e.getTransferable().getTransferData(DataFlavor(list,'List')))
			e.dropComplete(True)
			
	DropTarget(self,customDropListener(self))

```

I also used a custom `addData` function on the `List` here for the filtering.

```python
def addData(self,data):
	paths = self.data.getColumnAsList(0)
	
	if not paths and not self.data.columnCount:
		#this takes care of an empty dataset
		self.data = system.dataset.addColumn(self.data,[],'Paths',str)
	newRows = [[path] for path in data if not path in paths]
	self.data = system.dataset.addRows(self.data,newRows)

```

---

<div class="post-metadata">

**Author:** ![prasath.t](https://avatars.discourse-cdn.com/v4/letter/p/898d66/32.png) [@prasath.t](https://forum.inductiveautomation.com/u/prasath.t)\
**Post date:** [October 26, 2022, 10:06am UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479/4 "2022-10-26T10:06:42Z")

</div>

> [@lrose](#):
>
> ```auto
> def addData(self,data):
> paths = self.data.getColumnAsList(0)
> 	
> if not paths and not self.data.columnCount:
> #this takes care of an empty dataset
> self.data = system.dataset.addColumn(self.data,[],'Paths',str)
> newRows = [[path] for path in data if not path in paths]
> self.data = system.dataset.addRows(self.data,newRows)
> 
> ```

@lrose

one question

I have the t **ree view in a template** and i am using that template in window. how to call the tree view custom function in window InternalFrameActivated?
