• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JListの項目をドラッグ&ドロップ
#navi(../)
*JListの項目をドラッグ&ドロップ [#vdb92e79]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2004-02-16~
更新日:&lastmod;

#contents

**概要 [#va15d9c9]
JListをドラッグ&ドロップして、項目を入れ替えます。

#screenshot

**サンプルコード [#kadf6356]
#code{{
 public void dragOver(final DropTargetDragEvent e) {
   if(isDragAcceptable(e)) {
     e.acceptDrag(e.getDropAction());
   }else{
     e.rejectDrag();
     return;
   }
   Rectangle2D midArea   = new Rectangle2D.Float();
   Rectangle2D raCueLine = new Rectangle2D.Float();
   boolean flag   = false;
   int cellHeight = (int) getCellBounds(0,0).getHeight();
   int cellWidht  = (int) getCellBounds(0,0).getWidth();
   int modelSize  = getModel().getSize();
   Graphics2D g2  = (Graphics2D)getGraphics();
   for(int i=0;i<=modelSize;i++) {
     midArea.setRect(0, cellHeight*i-(cellHeight/2), cellWidht, cellHeight);
     if(midArea.contains(e.getLocation())) {
       flag = true;
       targetIndex = i;
       g2.setColor(lineColor);
       g2.setPaint(lineColor);
     }else{
       g2.setColor(getBackground());
       g2.setPaint(getBackground());
     }
     raCueLine.setRect(0, i*cellHeight, cellWidht, 2);
     g2.fill(raCueLine);
   }
   //セルの間にターゲットが無かった場合リストの一番下にラインを引く
   if(!flag) {
     targetIndex = modelSize;
     raCueLine.setRect(0, targetIndex*cellHeight, cellWidht, 2);
     g2.setColor(lineColor);
     g2.setPaint(lineColor);
     g2.fill(raCueLine);
   }
   //選択がずれないように…
   setSelectedIndex(draggedIndex);
 }

 public void drop(DropTargetDropEvent e) {
   DefaultListModel model = (DefaultListModel)getModel();
   Transferable t = e.getTransferable();
   DataFlavor[] f = t.getTransferDataFlavors();
   try {
     if(isDropAcceptable(e)) {
       Component comp = (Component) t.getTransferData(f[0]);
       Object str = model.getElementAt(draggedIndex);
       if(targetIndex==draggedIndex) {
         setSelectedIndex(targetIndex);
       }else if(targetIndex<draggedIndex) {
         model.removeElementAt(draggedIndex);
         model.insertElementAt(str, targetIndex);
         setSelectedIndex(targetIndex);
       }else{
         model.insertElementAt(str, targetIndex);
         model.removeElementAt(draggedIndex);
         setSelectedIndex(targetIndex-1);
       }
       e.dropComplete(true);
     }else{
       e.dropComplete(false);
     }
   }catch(UnsupportedFlavorException ex) {
     e.dropComplete(false);
   }catch(IOException ie) {
     e.dropComplete(false);
   }
   e.dropComplete(false);
   targetIndex = -1;
   repaint();
 }
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#na78421d]
上記のサンプルでは、ドラッグソースとドラッグターゲットの両方をJList自身に設定して、項目をドラッグ&ドロップしているように見せかけています。

複数アイテムを選択しての移動には対応していません。

**参考リンク [#qca3b1e2]
-[[How to Use Drag and Drop and Data Transfer>http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html]]
-[[DND from a JList with a single gesture>http://forum.java.sun.com/thread.jspa?threadID=465997]]
-[[Smoother Drag Drop JList JTable>http://forum.java.sun.com/thread.jspa?threadID=470025]]

**コメント [#m0be05ec]
- 以下を修正しました。 -- [[terai]] &new{2006-04-24 (月) 22:47:06};
--ドラッグで選択されたアイテムがずれにくいように修正
--ドロップしたあとアイテムが選択状態になるように修正
--アイテムの無い場所にドラッグすると一番最後の項目の下にラインを引くように修正(以前は一番下のアイテムの下半分にドラッグした場合のみ、そこに線を引いていた)
- アイテムを複数選択した状態でドラッグするとExceptionが発生する不具合を修正しました。 -- [[terai]] &new{2006-06-27 (火) 16:34:22};

#comment