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

#contents

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

#screenshot

**サンプルコード [#kadf6356]
#code{{
public void paintComponent(Graphics g) {
  super.paintComponent(g);
  if(targetIndex>=0) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setPaint(lineColor);
    g2.fill(targetLine);
  }
}
private void initTargetLine(Point p) {
  Rectangle2D testArea = new Rectangle2D.Float();
  int cellHeight = (int) getCellBounds(0,0).getHeight();
  int lineWidht  = (int) getCellBounds(0,0).getWidth();
  int lineHeight = 2;
  int modelSize  = getModel().getSize();
  targetIndex = -1;
  for(int i=0;i<modelSize;i++) {
    testArea.setRect(0, cellHeight*i-(cellHeight/2), lineWidht, cellHeight);
    if(testArea.contains(p)) {
      targetIndex = i;
      targetLine.setRect(0, i*cellHeight, lineWidht, lineHeight);
      break;
    }
  }
  if(targetIndex<0) {
    targetIndex = modelSize;
    targetLine.setRect(0, targetIndex*cellHeight-lineHeight, lineWidht, lineHeight);
  }
}
public void dragOver(final DropTargetDragEvent e) {
  if(isDragAcceptable(e)) {
    e.acceptDrag(e.getDropAction());
  }else{
    e.rejectDrag();
    return;
  }
  initTargetLine(e.getLocation());
  repaint();
}
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]
-[[Introduction to Drag and Drop and Data Transfer>http://java.sun.com/docs/books/tutorial/uiswing/dnd/intro.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};
- ドラッグ中マウスがJListの外に出た場合、カーソルを変更するように変更しました。 -- [[terai]] &new{2007-04-02 (月) 16:26:22};
- JTabeedPaneにJListを追加し、タブを2つ作りました。JListの項目を他のタブへD&Dすると、mouseReleasedメソッドが反応しないのですが、どうすれば回避できますでしょうヵ。 -- [[sao]] &new{2007-09-22 (土) 14:57:27};

#comment