JTable drag and drop
Oggi vi propongo una classe, per certi versi un pò "vecchiotta", per impostare il drag and drop su una JTable.
In sostanza voglio poter spostare le righe di una JTable, e metterle nell'ordine che mi pare.
Per ottenere questo dobbiamo impostare alcune opzioni e un transfer handler:
myTable.setDragEnabled(true);
myTable.setDropMode(DropMode.INSERT_ROWS);
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myTable.setTransferHandler(new MyTransferHandler());
Dove MyTransferHandler è una classe che estende TransferHandler.
La classe è questa qua:
public class MyTransferHandler extends TransferHandler {
private int[] rows = null;
private int addIndex = -1; // LOCAZIONE DELL'ITEM AGGIUNTO
private int addCount = 0; // NUMERO DI ITEMS AGGIUNTI
private final DataFlavor localObjectFlavor;
private Object[] transferedObjects = null;
private JComponent source = null;public MyTransferHandler() {
localObjectFlavor = new ActivationDataFlavor(Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items");
}@Override
protected Transferable createTransferable(JComponent c) {
source = c;
JTable table = (JTable) c;
DefaultTableModel model = (DefaultTableModel) table.getModel();
ArrayList@Override
public boolean canImport(TransferHandler.TransferSupport info) {
JTable t = (JTable) info.getComponent();
boolean b = info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
t.setCursor(b ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop);
return b;
}@Override
public int getSourceActions(JComponent c) {
return TransferHandler.COPY_OR_MOVE;
}@Override
public boolean importData(TransferHandler.TransferSupport info) {
JTable target = (JTable) info.getComponent();
JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
DefaultTableModel model = (DefaultTableModel) target.getModel();
int index = dl.getRow();
int max = model.getRowCount();
if (index < 0 || index > max) {
index = max;
}
addIndex = index;
target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
try {
Object[] values =
(Object[]) info.getTransferable().getTransferData(localObjectFlavor);
if (source == target) {
addCount = values.length;
}
for (int i = 0; i < values.length; i++) {
int idx = index++;
model.insertRow(idx, (Vector) values[i]);
target.getSelectionModel().addSelectionInterval(idx, idx);
}
return true;
} catch (UnsupportedFlavorException | IOException ufe) {
}
return false;
}@Override
protected void exportDone(JComponent c, Transferable t, int act) {
cleanup(c, act == MOVE);
}private void cleanup(JComponent src, boolean remove) {
if (remove && rows != null) {
JTable table = (JTable) src;
src.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
DefaultTableModel model = (DefaultTableModel) table.getModel();
if (addCount > 0) {
for (int i = 0; i < rows.length; i++) {
if (rows[i] >= addIndex) {
rows[i] += addCount;
}
}
}
for (int i = rows.length - 1; i >= 0; i--) {
model.removeRow(rows[i]);
}
}
rows = null;
addCount = 0;
addIndex = -1;
}
}
In effetti pare un pò lunga e complessa, ma in verità fa tutto da sola.
Visto che funziona, lascio a voi il compito di studiarla e migliorarla se vi va!
Enjoy!!
java jtable transferhandler drag and drop
Commentami!