简体   繁体   中英

Drag Drop Jtable rows

I'm new to Java and struggling with a conversion from VB.NET I need to re-order JTable rows and have followed the article on this forum :- [How do I drag and drop a row in a JTable?

Being a novice to java it's all a bit beyond me.

My JTable has a extended defaulttablemodel thus:-

       denominationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       denominationTable.getTableHeader().setReorderingAllowed(false);
       denominationTable.setAutoCreateRowSorter(true);

       DefaultTableModel denominationReorderableTableModel = new ReorderableTableModel();

       denominationReorderableTableModel.addColumn("Denomination");

       denominationTable.setModel(denominationReorderableTableModel);
       denominationTable.getColumnModel().getColumn(0).setPreferredWidth(100);    
       denominationTable.setDragEnabled(true);
       denominationTable.setDropMode(DropMode.INSERT_ROWS);
       denominationTable.setTransferHandler(new TableRowTransferHandler(denominationTable)); 

ReorderableTableModel looks like this:

  public class ReorderableTableModel extends DefaultTableModel {

            public interface Reorderable {

                   public void reorder(int fromIndex, int toIndex);
        }

        }

TableRowTransferHandler is as per the article referred to thus:-

     /**
      * Handles drag & drop row reordering
      */
     public class TableRowTransferHandler extends TransferHandler {
     private final DataFlavor localObjectFlavor = new ActivationDataFlavor(Integer.class    DataFlavor.javaJVMLocalObjectMimeType, "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) {
         table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      }
   }

}

I've noticed that if I add a method to denominationReorderableTableModel as per

DefaultTableModel denominationReorderableTableModel = new ReorderableTableModel();

it is not visible! neither is Reorderable.

Netbeans does not complain about anything.

When I run it and try to re-order the rows I get:-

java.lang.ClassCastException: mycoins.ReorderableTableModel cannot be cast to mycoins.ReorderableTableModel$Reorderable
at mycoins.TableRowTransferHandler.importData(TableRowTransferHandler.java:64)
at javax.swing.TransferHandler$DropHandler.drop(TransferHandler.java:1536)
at java.awt.dnd.DropTarget.drop(DropTarget.java:450)
at javax.swing.TransferHandler$SwingDropTarget.drop(TransferHandler.java:1274)
at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:537)
at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:851)
at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:775)
at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
at java.awt.Component.dispatchEventImpl(Component.java:4716)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4566)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4417)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Two days of research and I'm no further forward. I can't find any reference that gives me a clue.

I even tried with an abstracttable model - same result.

It's probably a newbie stupid error.

Your thoughts/comments please.

Read the section from the Swing tutorial on Drag and Drop to understand the basics of how DnD works. Basically you need to create a TransferHandler that supports dropping the data into your TableModel.

Here is a link to the old ExtendedDnDDemo code that was included in the previous version of the above tutorial. It includes a TransferHandler for a JTable.

I have a working example from another source.( camickr )

BUT it's very different from the one I was trying.

The author of the original has relpied to a personal email:-

You need to make your custom table model a subclass of the DefaultTableModel and then you need declare it to implement my 'Reorderable' interface. I recommend taking the official java tutorial (see sun/oracle java website) and reading up on class inheritance and interfaces.

Thanks for all the input - I obviously have a lot to learn about Java

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM