2012-09-24 188 views
2

所以我为我的应用程序编写了一个TransferHandler(沿着Oracle站点的示例),但是当我尝试移动数据时它并未移动。它所做的就是复制索引处的数据(n-1,即,如果我正在移动并且项目到n位置)来索引n。你能否请检查什么是错误的,虽然我尝试了很多选择,但没有一个为我工作。在JList中拖放不起作用

import javax.swing.TransferHandler; 
import javax.swing.*; 
import java.awt.datatransfer.*; 

    public class ListTransferHandler extends TransferHandler { 
     private int[] indices = null; 
     private int addIndex = -1; //Location where items were added 
     private int addCount = 0; //Number of items added. 

     public boolean canImport(TransferHandler.TransferSupport info) { 
      // Check for String flavor 
      if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) { 
       return false; 
      } 
      return true; 
     } 

     protected Transferable createTransferable(JComponent c) { 
      return new StringSelection(exportString(c)); 
     } 

     public int getSourceActions(JComponent c) { 
      return TransferHandler.MOVE; 
     } 

     public boolean importData(TransferHandler.TransferSupport info) { 
      if (!info.isDrop()) { 
       return false; 
      } 

      JList list = (JList)info.getComponent(); 
      DefaultListModel listModel = (DefaultListModel)list.getModel(); 
      JList.DropLocation dl = (JList.DropLocation)info.getDropLocation(); 
      int index = dl.getIndex(); 
      boolean insert = dl.isInsert(); 

      // Get the string that is being dropped. 
      Transferable t = info.getTransferable(); 
      String data; 
      try { 
       data = (String)t.getTransferData(DataFlavor.stringFlavor); 
      } 
      catch (Exception e) { return false; } 

      // Perform the actual import. 
      if (insert) { 
       listModel.add(index, data); 
      } else { 
       listModel.set(index, data); 
      } 
      return true; 
     } 

     protected void exportDone(JComponent c, Transferable data, int action) { 
      cleanup(c, action == TransferHandler.MOVE); 
     } 

     //Bundle up the selected items in the list 
     //as a single string, for export. 
     protected String exportString(JComponent c) { 
      JList list = (JList)c; 
      indices = list.getSelectedIndices(); 
      Object[] values = list.getSelectedValues(); 

      StringBuffer buff = new StringBuffer(); 

      for (int i = 0; i < values.length; i++) { 
       Object val = values[i]; 
       buff.append(val == null ? "" : val.toString()); 
       if (i != values.length - 1) { 
        buff.append("\n"); 
       } 
      } 

      return buff.toString(); 
     } 

     //Take the incoming string and wherever there is a 
     //newline, break it into a separate item in the list. 
     protected void importString(JComponent c, String str) { 
      JList target = (JList)c; 
      DefaultListModel listModel = (DefaultListModel)target.getModel(); 
      int index = target.getSelectedIndex(); 

      //Prevent the user from dropping data back on itself. 
      //For example, if the user is moving items #4,#5,#6 and #7 and 
      //attempts to insert the items after item #5, this would 
      //be problematic when removing the original items. 
      //So this is not allowed. 
      if (indices != null && index >= indices[0] - 1 && 
        index <= indices[indices.length - 1]) { 
       indices = null; 
       return; 
      } 

      int max = listModel.getSize(); 
      if (index < 0) { 
       index = max; 
      } else { 
       index++; 
       if (index > max) { 
        index = max; 
       } 
      } 
      addIndex = index; 
      String[] values = str.split("\n"); 
      addCount = values.length; 
      for (int i = 0; i < values.length; i++) { 
       listModel.add(index++, values[i]); 
      } 
     } 

     //If the remove argument is true, the drop has been 
     //successful and it's time to remove the selected items 
     //from the list. If the remove argument is false, it 
     //was a Copy operation and the original list is left 
     //intact. 
     protected void cleanup(JComponent c, boolean remove) { 
      if (remove && indices != null) { 
       JList source = (JList)c; 
       DefaultListModel model = (DefaultListModel)source.getModel(); 
       //If we are moving items around in the same list, we 
       //need to adjust the indices accordingly, since those 
       //after the insertion point have moved. 
       if (addCount > 0) { 
        for (int i = 0; i < indices.length; i++) { 
         if (indices[i] > addIndex) { 
          indices[i] += addCount; 
         } 
        } 
       } 
       for (int i = indices.length - 1; i >= 0; i--) { 
        model.remove(indices[i]); 
       } 
      } 
      indices = null; 
      addCount = 0; 
      addIndex = -1; 
     } 
} 

回答

2

一旦导出成功完成,您需要从源中“删除”数据。

为了做到这一点,您需要覆盖TransferHandler.exportDone方法。

保护无效exportDone(JComponent的源, 转换数据, INT动作)

数据已出口后调用。如果动作是MOVE,此方法应删除已传输的 数据。

由于MOVE不是受支持的 此实现的操作(getSourceActions不包括 MOVE),所以此方法无法执行任何操作。

基本上,从那里你需要检查action类型,并确保目标组件接受了MOVE,而不是简单地COPY“主编,并从源列表中删除的元素。