Swing/DnDTable のバックアップ(No.5)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/DnDTable へ行く。
- 1 (2007-04-02 (月) 16:29:09)
- 2 (2007-04-03 (火) 15:01:35)
- 3 (2007-08-21 (火) 13:13:10)
- 4 (2009-11-16 (月) 10:53:32)
- 5 (2010-03-08 (月) 12:30:36)
- 6 (2010-03-08 (月) 13:42:39)
- 7 (2011-03-04 (金) 15:01:42)
- 8 (2011-03-29 (火) 09:26:39)
- 9 (2013-02-09 (土) 23:49:23)
- 10 (2013-05-03 (金) 23:48:34)
- 11 (2014-09-30 (火) 01:04:55)
- 12 (2014-12-03 (水) 00:27:03)
- 13 (2016-01-27 (水) 18:20:16)
- 14 (2016-05-22 (日) 21:25:46)
- 15 (2016-05-26 (木) 01:05:18)
- 16 (2016-05-26 (木) 14:47:08)
- 17 (2016-10-28 (金) 21:55:46)
- 18 (2017-11-15 (水) 15:50:55)
- 19 (2018-05-30 (水) 20:16:33)
- 20 (2019-10-15 (火) 17:32:35)
- 21 (2021-05-19 (水) 05:41:38)
TITLE:JTableの行をドラッグ&ドロップ
Posted by terai at 2007-04-02
JTableの行をドラッグ&ドロップ
JTableの行をドラッグ&ドロップで入れ替えます。
- &jnlp;
- &jar;
- &zip;
#screenshot
サンプルコード
class DnDTable extends JTable implements DragGestureListener, DragSourceListener, Transferable {
private static final String NAME = "test";
private static final Color lineColor = new Color(255,100,100);
private Rectangle2D targetLine = new Rectangle2D.Float();
private int draggedIndex = -1;
private int targetIndex = -1;
public DnDTable(TableModel model) {
super(model);
DropTarget dropTarget = new DropTarget(this,
DnDConstants.ACTION_COPY_OR_MOVE, new CDropTargetListener(), true);
DragSource dragSource = new DragSource();
dragSource.createDefaultDragGestureRecognizer((Component)this,
DnDConstants.ACTION_COPY_OR_MOVE, (DragGestureListener)this);
}
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 = getRowHeight();
int lineWidht = getWidth();
int lineHeight = 2;
int modelSize = getRowCount();
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);
}
}
// Interface: DragGestureListener
public void dragGestureRecognized(DragGestureEvent e) {
if(getSelectedRowCount()>1) return;
draggedIndex = rowAtPoint(e.getDragOrigin());
if(draggedIndex<0) return;
try{
e.startDrag(DragSource.DefaultMoveDrop, (Transferable)this, (DragSourceListener)this);
}catch(InvalidDnDOperationException idoe) {}
}
// Interface: DragSourceListener
public void dragEnter(DragSourceDragEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}
public void dragExit(DragSourceEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
}
public void dragOver(DragSourceDragEvent e) {}
public void dropActionChanged(DragSourceDragEvent e) {}
public void dragDropEnd(DragSourceDropEvent e) {}
// Interface: Transferable
private final DataFlavor FLAVOR
= new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType, NAME);
public Object getTransferData(DataFlavor flavor) {
return this;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] f = new DataFlavor[1];
f[0] = this.FLAVOR;
return f;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.getHumanPresentableName().equals(NAME);
}
class CDropTargetListener implements DropTargetListener{
// DropTargetListener interface
public void dragExit(DropTargetEvent e) {
targetIndex = -1;
repaint();
}
public void dragEnter(DropTargetDragEvent e) {
if(isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
}else{
e.rejectDrag();
}
}
public void dragOver(final DropTargetDragEvent e) {
if(isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
}else{
e.rejectDrag();
return;
}
initTargetLine(e.getLocation());
repaint();
}
public void dropActionChanged(DropTargetDragEvent e) {
// if(isDragAcceptable(e)) e.acceptDrag(e.getDropAction());
// else e.rejectDrag();
}
public void drop(DropTargetDropEvent e) {
DefaultTableModel model = (DefaultTableModel)getModel();
Transferable t = e.getTransferable();
DataFlavor[] f = t.getTransferDataFlavors();
try {
if(isDropAcceptable(e)) {
Component comp = (Component) t.getTransferData(f[0]);
if(targetIndex==draggedIndex) {
setRowSelectionInterval(targetIndex,targetIndex);
}else{
int tg = (targetIndex<draggedIndex)?targetIndex:targetIndex-1;
model.moveRow(draggedIndex,draggedIndex,tg);
setRowSelectionInterval(tg,tg);
}
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();
}
public boolean isDragAcceptable(DropTargetDragEvent e) {
DataFlavor[] f = e.getCurrentDataFlavors();
return isDataFlavorSupported(f[0]);
}
public boolean isDropAcceptable(DropTargetDropEvent e) {
Transferable t = e.getTransferable();
DataFlavor[] f = t.getTransferDataFlavors();
return isDataFlavorSupported(f[0]);
}
}
}
解説
ドラッグソースとドラッグターゲットをどちらもJTableにして、行の入れ替えがドラッグ&ドロップで出来るようになっています。
このサンプルのドラッグ&ドロップの手順などは、JListの項目をドラッグ&ドロップとほとんど同一です*1。
複数アイテムを選択しての移動には対応していません。
参考リンク
- JListの項目をドラッグ&ドロップ
- JTable自体の高さを拡張
- TransferHandlerを使ってJTableの行をドラック&ドロップ、並べ替え
- JTableの行を別のJTableにドラッグして移動