How do I drag and drop a row in a JTable?

前端 未结 5 1532
既然无缘
既然无缘 2020-12-08 01:03

How do you setup a JTable to be able to drag a row to a different index in the table. For example if I have 5 rows and I want to drag the 4th row to the 2nd position?

相关标签:
5条回答
  • 2020-12-08 01:17

    Check out the drag and drop section of the Java Tutorial. There are some examples on how to implement this for JTable.

    0 讨论(0)
  • 2020-12-08 01:21

    The following allows JTable re-ordering of a single dragged row:

      table.setDragEnabled(true);
      table.setDropMode(DropMode.INSERT_ROWS);
      table.setTransferHandler(new TableRowTransferHandler(table)); 
    

    Your TableModel should implement the following to allow for re-ordering:

    public interface Reorderable {
       public void reorder(int fromIndex, int toIndex);
    }
    

    This TransferHandler class handles the drag & drop, and calls reorder() on your TableModel when the gesture is completed.

    /**
     * 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));
          }
       }
    
    }
    
    0 讨论(0)
  • 2020-12-08 01:24

    Just for the records and multiple row re-ordering:

    use somewhere....

     JTable table = t_objects;
        table.setDragEnabled(true);
        table.setDropMode(DropMode.INSERT_ROWS);
        table.setTransferHandler(new TableRowTransferHandler(table));
    

    This is the main class in the above answer, I modified that to match the needs for multiple row DnD. All I did was to use the first selected row, then calculate the rows above the drop place. Removed seleced items and keep them in a list of objects (row array object). then insert them back to calculated row. and finally select the removed/dragged rows to complete the process.

    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));
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 01:25

    I like Soley's modifications, but his code relies on an external library, and I'm not sure where he got it from, so I re-wrote it so that you don't need the TableUtil class...

     @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 iter = 0;
                    for (int row : rows) {
                        if (index > row) {
                            index--;
                            ((Reorderable) table.getModel()).reorder(row - iter, index);
                        }
    
                        else {
                            ((Reorderable) table.getModel()).reorder(row, index);
                        }
                        index++;
                        iter++;
                    }
    
                    target.getSelectionModel().addSelectionInterval(index, index);
    
                    return true;
                }
    
          } catch (Exception e) {
                String error = e.getMessage();
                JOptionPane.showMessageDialog(null, error, "Error", JOptionPane.ERROR_MESSAGE);
          }
          return false;
       }
    
    0 讨论(0)
  • 2020-12-08 01:27

    perhaps sth. like this:

        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) {
        }
    });
    
    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题