TITLE:JListの項目をドラッグ&ドロップ
Posted by aterai at 2004-02-16

JListの項目をドラッグ&ドロップ

JListをドラッグ&ドロップして、項目を入れ替えます。
  • category: swing folder: DnDList title: JListの項目をドラッグ&ドロップ tags: [JList, DragAndDrop] author: aterai pubdate: 2004-02-16 description: JListをドラッグ&ドロップして項目を入れ替えます。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTLb3DW2ZI/AAAAAAAAAXk/8VfeirUfaoo/s800/DnDList.png

概要

JListをドラッグ&ドロップして項目を入れ替えます。
DnDList.png

サンプルコード

#spanend
#spandel
public void paintComponent(Graphics g) {
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
@Override protected void paintComponent(Graphics g) {
#spanend
  super.paintComponent(g);
  if(targetIndex>=0) {
    Graphics2D g2 = (Graphics2D)g;
  if (targetIndex >= 0) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setPaint(lineColor);
    g2.fill(targetLine);
    g2.dispose();
  }
}
#spanadd

#spanend
private void initTargetLine(Point p) {
  Rectangle2D testArea = new Rectangle2D.Float();
  int cellHeight = (int) getCellBounds(0,0).getHeight();
  int lineWidht  = (int) getCellBounds(0,0).getWidth();
  Rectangle rect = getCellBounds(0, 0);
  int cellHeight = rect.height;
  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)) {
  targetLine.setSize(rect.width, lineHeight);
  for (int i = 0; i < modelSize; i++) {
    rect.setLocation(0, cellHeight * i - cellHeight / 2);
    if (rect.contains(p)) {
      targetIndex = i;
      targetLine.setRect(0, i*cellHeight, lineWidht, lineHeight);
      targetLine.setLocation(0, i * cellHeight);
      break;
    }
  }
  if(targetIndex<0) {
  if (targetIndex < 0) {
    targetIndex = modelSize;
    targetLine.setRect(0, targetIndex*cellHeight-lineHeight, lineWidht, lineHeight);
    targetLine.setLocation(0, targetIndex * cellHeight - lineHeight);
  }
}
#spandel
public void dragOver(final DropTargetDragEvent e) {
#spanend
  if(isDragAcceptable(e)) {
#spanadd

#spanend
#spanadd
@Override public void dragOver(final DropTargetDragEvent e) {
#spanend
  if (isDragAcceptable(e)) {
    e.acceptDrag(e.getDropAction());
  }else{
  } else {
    e.rejectDrag();
    return;
  }
  initTargetLine(e.getLocation());
  repaint();
}
#spandel
public void drop(DropTargetDropEvent e) {
#spanend
  DefaultListModel model = (DefaultListModel)getModel();
#spanadd

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

解説

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

解説

上記のサンプルでは、ドラッグソースとドラッグターゲットの両方をJList自身に設定して、項目をドラッグ&ドロップしているように見せかけています。 複数アイテムを選択しての移動には対応していません。

参考リンク

参考リンク

コメント

  • 以下を修正しました。 -- aterai
    • ドラッグで選択されたアイテムがずれにくいように修正
    • ドロップしたあとアイテムが選択状態になるように修正
    • アイテムの無い場所にドラッグすると一番最後の項目の下にラインを引くように修正(以前は一番下のアイテムの下半分にドラッグした場合のみ、そこに線を引いていた)
  • アイテムを複数選択した状態でドラッグするとExceptionが発生する不具合を修正しました。 -- aterai
  • ドラッグ中マウスがJListの外に出た場合、カーソルを変更するように変更しました。 -- aterai
  • JTabeedPaneにJListを追加し、タブを2つ作りました。JListの項目を他のタブへD&Dすると、mouseReleasedメソッドが反応しないのですが、どうすれば回避できますでしょうヵ。 -- sao
    • 削除しました - src2.zip を作ってXP+1.6.0_02で試してみたのですが、JListの項目を他のタブへD&D出来ないようです。環境が違うのかな? -- aterai
  • ぉー!ファイル、わざわざありがとうございます!自分なりに頑張ってます。私がやりたのはJListの項目をタブへD&Dして項目に書かれている内容を他のタブ(の持ってるJList)へ渡したいんです。現状は、2つ以上の項目なら渡せて、1つだとエラーがでてしまいます。よくわかっていないまま進めてるので、全然わからないです(汗) -- sao
    • あ、src2.zipは的外れでしたね。このページのDnDListをJTabbedPaneに入れて、項目をタブタイトルにドロップするとExceptionの発生するバグがあるのかも?と勘違いしていました。このページのサンプルを改造するなら、src2.zipではなく、http://terai.xrea.jp/swing/dropontabtitle/src.zip *1、チュートリアルならDragListDemo が参考になるかも。 -- aterai
  • scr3ありがとうございます☆軽快に動きますね!すごく!src3ですが、DnDListにsetEnabled(true);を追加しました。が、まったくわからず…思いのほか、2項目以上のD&Dって難しいですネ(汗 -- sao

コメント