概要

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

サンプルコード

@Override protected void paintComponent(Graphics g) {
  super.paintComponent(g);
  if (targetIndex >= 0) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setPaint(lineColor);
    g2.fill(targetLine);
    g2.dispose();
  }
}

private void initTargetLine(Point p) {
  Rectangle rect = getCellBounds(0, 0);
  int cellHeight = rect.height;
  int lineHeight = 2;
  int modelSize  = getModel().getSize();
  targetIndex = -1;
  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.setLocation(0, i * cellHeight);
      break;
    }
  }
  if (targetIndex < 0) {
    targetIndex = modelSize;
    targetLine.setLocation(0, targetIndex * cellHeight - lineHeight);
  }
}

@Override public void dragOver(final DropTargetDragEvent e) {
  if (isDragAcceptable(e)) {
    e.acceptDrag(e.getDropAction());
  } else {
    e.rejectDrag();
    return;
  }
  initTargetLine(e.getLocation());
  repaint();
}

@Override 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 | IOException ex) {
    e.dropComplete(false);
  }
  e.dropComplete(false);
  targetIndex = -1;
  repaint();
}
View in GitHub: Java, Kotlin

解説

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

参考リンク

コメント