Comment configurez-vous un JTable pour pouvoir faire glisser une ligne vers un autre index de la table. Par exemple, si j'ai 5 lignes et que je veux faire glisser la 4e ligne vers la 2e position?
Consultez la section drag and drop du didacticiel Java. Il existe quelques exemples sur la façon de mettre en œuvre ceci pour JTable
.
Ce qui suit permet à JTable de réorganiser une seule ligne glissée:
table.setDragEnabled(true);
table.setDropMode(DropMode.INSERT_ROWS);
table.setTransferHandler(new TableRowTransferHandler(table));
Votre TableModel doit implémenter les éléments suivants pour permettre la réorganisation:
public interface Reorderable {
public void reorder(int fromIndex, int toIndex);
}
Cette classe TransferHandler gère le glisser-déposer et appelle reorder () sur votre TableModel une fois le geste terminé.
/**
* Handles drag & drop row reordering
*/
public class TableRowTransferHandler extends TransferHandler {
private final DataFlavor localObjectFlavor = new ActivationDataFlavor(Integer.class, "application/x-Java-Integer;class=Java.lang.Integer", "Integer Row Index");
private JTable table = null;
public TableRowTransferHandler(JTable table) {
this.table = table;
}
@Override
protected Transferable createTransferable(JComponent c) {
assert (c == table);
return new DataHandler(new Integer(table.getSelectedRow()), localObjectFlavor.getMimeType());
}
@Override
public boolean canImport(TransferHandler.TransferSupport info) {
boolean b = info.getComponent() == table && info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
table.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();
int index = dl.getRow();
int max = table.getModel().getRowCount();
if (index < 0 || index > max)
index = max;
target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
try {
Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor);
if (rowFrom != -1 && rowFrom != index) {
((Reorderable)table.getModel()).reorder(rowFrom, index);
if (index > rowFrom)
index--;
target.getSelectionModel().addSelectionInterval(index, index);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
protected void exportDone(JComponent c, Transferable t, int act) {
if ((act == TransferHandler.MOVE) || (act == TransferHandler.NONE)) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}
Juste pour les enregistrements et la réorganisation de plusieurs lignes:
utiliser quelque part ....
JTable table = t_objects;
table.setDragEnabled(true);
table.setDropMode(DropMode.INSERT_ROWS);
table.setTransferHandler(new TableRowTransferHandler(table));
Ceci est la classe principale dans la réponse ci-dessus, j'ai modifié cela pour répondre aux besoins de plusieurs lignes DnD. Tout ce que j'ai fait était d'utiliser la première ligne sélectionnée, puis de calculer les lignes au-dessus du lieu de dépôt. Supprimez les éléments sélectionnés et conservez-les dans une liste d'objets (objet de tableau en lignes). insérez-les ensuite dans la ligne calculée. et enfin sélectionnez les lignes supprimées/glissées pour terminer le processus.
public class TableRowTransferHandler extends TransferHandler {
private final DataFlavor localObjectFlavor = new DataFlavor(Integer.class, "Integer Row Index");
private JTable table = null;
public TableRowTransferHandler(JTable table) {
this.table = table;
}
@Override
protected Transferable createTransferable(JComponent c) {
assert (c == table);
return new DataHandler(new Integer(table.getSelectedRow()), localObjectFlavor.getMimeType());
}
@Override
public boolean canImport(TransferHandler.TransferSupport info) {
boolean b = info.getComponent() == table && info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
table.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();
int index = dl.getRow();
int max = table.getModel().getRowCount();
if (index < 0 || index > max) {
index = max;
}
target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
try {
Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor);
if (rowFrom != -1 && rowFrom != index) {
int[] rows = table.getSelectedRows();
int dist = 0;
for (int row : rows) {
if (index > row) {
dist++;
}
}
index -= dist;
//**TableUtil** is a simple class that just copy, remove and select rows.
ArrayList<Object> list = TableUtil.getSelectedList(table);
TableUtil.removeSelected(table);
ArrayList<Integer> sels = new ArrayList<Integer>();
for (Object obj : list) {
sels.add(index);
TableUtil.addRowAt(table, obj, index++);
}
TableUtil.selectMultipleRow(table, sels);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
protected void exportDone(JComponent c, Transferable t, int act) {
if (act == TransferHandler.MOVE) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}
peut-être qc comme ça:
table.addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
e.consume();
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.MOVE);
}
public void mouseMoved(MouseEvent e) {
}
});