Swing/DnDTable の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DnDTable へ行く。
- Swing/DnDTable の差分を削除
--- category: swing folder: DnDTable title: JTableの行をドラッグ&ドロップ tags: [JTable, DragAndDrop] author: aterai pubdate: 2007-04-02T16:29:09+09:00 description: JTableの行を選択し、その順序をドラッグ&ドロップで入れ替えます。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTLl0NAFoI/AAAAAAAAAX0/su1r-c7f4V0/s800/DnDTable.png --- * 概要 [#summary] `JTable`の行を選択し、その順序をドラッグ&ドロップで入れ替えます。 #download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTLl0NAFoI/AAAAAAAAAX0/su1r-c7f4V0/s800/DnDTable.png) * サンプルコード [#sourcecode] #code(link){{ class DnDTable extends JTable implements DragGestureListener, Transferable { private static final String NAME = "test"; private static final DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType, NAME); private static final Color LINE_COLOR = new Color(255, 100, 100); private final 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(); new DragSource().createDefaultDragGestureRecognizer( (Component) this, DnDConstants.ACTION_COPY_OR_MOVE, (DragGestureListener) this); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (targetIndex >= 0) { Graphics2D g2 = (Graphics2D) g.create(); g2.setPaint(LINE_COLOR); g2.fill(targetLine); g2.dispose(); } } private void initTargetLine(Point p) { Rectangle2D testArea = new Rectangle2D.Float(); int cellHeight = getRowHeight(); int lineWidth = getWidth(); int lineHeight = 2; int modelSize = getRowCount(); targetIndex = -1; for (int i = 0; i < modelSize; i++) { testArea.setBounds( 0, cellHeight * i - cellHeight / 2, lineWidth, cellHeight); if (testArea.contains(p)) { targetIndex = i; targetLine.setBounds(0, i * cellHeight, lineWidth, lineHeight); break; } } if (targetIndex < 0) { targetIndex = modelSize; targetLine.setBounds( 0, targetIndex * cellHeight - lineHeight, lineWidth, lineHeight); } } // Interface: DragGestureListener @Override public void dragGestureRecognized(DragGestureEvent e) { if (getSelectedRowCount() > 1) { return; } draggedIndex = rowAtPoint(e.getDragOrigin()); if (draggedIndex < 0) { return; } try { e.startDrag(DragSource.DefaultMoveDrop, (Transferable) this, new TableDragSourceListener()); } catch (InvalidDnDOperationException idoe) { idoe.printStackTrace(); } } // Interface: Transferable @Override public Object getTransferData(DataFlavor flavor) { return this; } @Override public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] {FLAVOR}; } @Override public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.getHumanPresentableName().equals(NAME); } class CDropTargetListener implements DropTargetListener { @Override public void dragExit(DropTargetEvent e) { targetIndex = -1; repaint(); } @Override public void dragEnter(DropTargetDragEvent e) { if (isDragAcceptable(e)) { e.acceptDrag(e.getDropAction()); } else { e.rejectDrag(); } } @Override public void dragOver(final DropTargetDragEvent e) { if (isDragAcceptable(e)) { e.acceptDrag(e.getDropAction()); setCursor(DragSource.DefaultMoveDrop); } else { e.rejectDrag(); setCursor(DragSource.DefaultMoveNoDrop); return; } initTargetLine(e.getLocation()); repaint(); } @Override public void dropActionChanged(DropTargetDragEvent e) { // if (isDragAcceptable(e)) { e.acceptDrag(e.getDropAction()); } // else e.rejectDrag(); } @Override public void drop(DropTargetDropEvent e) { DefaultTableModel model = (DefaultTableModel) getModel(); if (isDropAcceptable(e)) { 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); } e.dropComplete(false); setCursor(Cursor.getDefaultCursor()); targetIndex = -1; repaint(); } private boolean isDragAcceptable(DropTargetDragEvent e) { DataFlavor[] f = e.getCurrentDataFlavors(); return isDataFlavorSupported(f[0]); } private boolean isDropAcceptable(DropTargetDropEvent e) { Transferable t = e.getTransferable(); DataFlavor[] f = t.getTransferDataFlavors(); return isDataFlavorSupported(f[0]); } } } }} * 解説 [#explanation] ドラッグソースとドラッグターゲットをどちらも`JTable`にして、行の入れ替えがドラッグ&ドロップで可能になっています。 このサンプルのドラッグ&ドロップの手順は、行の入れ替え処理などを除けば[[JListの項目をドラッグ&ドロップ>Swing/DnDList]]と同等です。 * 参考リンク [#reference] - [[JListの項目をドラッグ&ドロップ>Swing/DnDList]] - [[JTable自体の高さを拡張>Swing/FillsViewportHeight]] - [[TransferHandlerを使ってJTableの行をドラッグ&ドロップ、並べ替え>Swing/DnDReorderTable]] -- `Java 1.6.0`以上で複数行を選択して移動を行う場合のサンプル - [[JTableの行を別のJTableにドラッグして移動>Swing/DragRowsAnotherTable]] - [[JTree間でのドラッグ&ドロップによるノードの移動>Swing/DnDBetweenTrees]] * コメント [#comment] #comment #comment