Home / Programmazione / Java / JTable drag and drop
Mattepuffo

JTable drag and drop

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();
        ArrayListlist = new ArrayList<>();
        for (int i : rows = table.getSelectedRows()) {
            list.add(model.getDataVector().elementAt(i));
        }
        transferedObjects = list.toArray();
        return new DataHandler(transferedObjects, localObjectFlavor.getMimeType());
    }

    @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!!