This is a Jython translation of Sun's Java example of how extend drag and drop functionality. It omits the JTable component but this should be easy to add. Although not perfect, hopefully it may be of use to someone and demonstrate how easy DnD is to implement and extend in Jython:

import javax.swing as swing
import java.awt as awt
import java.awt.datatransfer as dt
import java.awt.event as event
import java.io.IOException as ioexception
import java.lang as lang


class dnddemo(swing.JPanel):
    
    def __init__(self):
        awt.GridLayout(3,1)
        self.add(self.createArea())
        self.add(self.createList())

    def createList(self): 
        listModel = swing.DefaultListModel()
        listModel.addElement("List 0")
        listModel.addElement("List 1")
        listModel.addElement("List 2")
        listModel.addElement("List 3")
        listModel.addElement("List 4")
        listModel.addElement("List 5")
        listModel.addElement("List 6")
        listModel.addElement("List 7")
        listModel.addElement("List 8")

        list = swing.JList(listModel)
        list.setSelectionMode(swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION)
        scrollPane = swing.JScrollPane(list)
        scrollPane.setPreferredSize(awt.Dimension(400,100))
        list.setDragEnabled(True)
        list.setTransferHandler(ListTransferHandler())

        panel = swing.JPanel(awt.BorderLayout())
        panel.add(scrollPane, awt.BorderLayout.CENTER)
        panel.setBorder(swing.BorderFactory.createTitledBorder("List"))
        return panel
    
    def createArea(self): 
        text = "This is the text that I want to show."
        area = swing.JTextArea()
        area.setText(text)
        area.setDragEnabled(True)
        scrollPane = swing.JScrollPane(area)
        scrollPane.setPreferredSize(awt.Dimension(400,100))
        panel = swing.JPanel(awt.BorderLayout())
        panel.add(scrollPane, awt.BorderLayout.CENTER)
        panel.setBorder(swing.BorderFactory.createTitledBorder("Text Area"))
        return panel

    def createAndShowGUI(self):
        frame = swing.JFrame("Jython DND List Demo")
        frame.setDefaultCloseOperation(swing.JFrame.EXIT_ON_CLOSE)
        newContentPane = dnddemo()
        newContentPane.setOpaque(True)
        frame.setContentPane(newContentPane)
        frame.pack()
        frame.setVisible(True)

    
class StringTransferHandler(swing.TransferHandler):
    
    def createTransferable(self,JComponent):
        return dt.StringSelection(self.exportString(JComponent))
    
    def getSourceActions(self,JComponent): 
        return swing.TransferHandler.COPY_OR_MOVE
    
    def importData(self,JComponent,Transferable):
        if self.canImport(JComponent, Transferable.getTransferDataFlavors()):
            try: 
                st = str(Transferable.getTransferData(dt.DataFlavor.stringFlavor))
                self.importString(JComponent, st)
                return True
            except UnsupportedFlavorException, ufe:
                print "unsupportedflavor:"+str(ufe)
            except ioexception,ioe: 
                print "ioexception:"+str(ioe)
        return False
    
    def exportDone(self,JComponent,data,action): 
        tst = False
        if action == swing.TransferHandler.MOVE:tst = True
        self.cleanup(JComponent,tst)
    
    def canImport(self,JComponent,flavors): 
        for i in range(0,len(flavors)):
            if dt.DataFlavor.stringFlavor.equals(flavors[i]):return True
        return False


class ListTransferHandler(StringTransferHandler):

    def __init__(self):
      self.indices = []
      self.addIndex = -1
      self.addCount = 0
            
    def exportString(self,jlist):
        self.indices = jlist.getSelectedIndices()
        values = jlist.getSelectedValues()
        buff = lang.StringBuffer()
        for i in range(0, len(values)):
            val = values[i]
            if val == None:buff.append("")
            else:buff.append(str(val))
            l = len(values)-1 
            if i != l: 
                buff.append("\n")
        return str(buff)

    def importString(self,target,st): 
        listModel = target.getModel()
        index = target.getSelectedIndex()
        max = listModel.getSize()
        if index < 0: 
            index = max
        else: 
            index =+1
            if index > max:
                index = max
        self.addIndex = index
        values = st.split("\n")
        current = []
        for i in range(0,listModel.getSize()):
            current.append(listModel.getElementAt(i))
        for i in range(0,len(values)): 
            index =+ 1
            if values[i] not in current:
                listModel.add(index,values[i])
                self.addCount =+1

    def cleanup(self,source,remove): 
        if remove and len(self.indices) > 0 : 
            model  = source.getModel()
            if self.addCount > 0:
                for i in range(0,len(self.indices)): 
                    if self.indices[i] > self.addIndex: 
                        self.indices[i] =+ self.addCount
            for i in range(0,len(self.indices)): 
                model.remove(self.indices[i])
        self.indices = []
        self.addCount = 0
        self.addIndex = -1


if __name__ == "__main__":
  demo = dnddemo()
  demo.createAndShowGUI()   

The original Sun example is available at: http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html#complex

Cheers Colin

JythonMonthly/Articles/November2006/1 (last edited 2008-11-15 09:16:01 by localhost)