Drag N Drop in JTables

Hi !
I have two scenarios
1) I need to be able to drag and drop rows from a given table to the other table.
2) I should be able to drag and drop rows with in the same table( This case is same as rearranging the rows with in the table with the help of MouseDragged Event).
Is this possible using Drag N Drop in swing? Greatly appreciate solutions and online resources which can help me write my custom TransferHandler for the above purposes

Ok, here's the promised source code
When the Class is initialized you need to create a couple of objects
          DragSource dragSource = DragSource.getDefaultDragSource() ;
          dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this) ;And you will need the following method
     public void dragGestureRecognized(DragGestureEvent e) {
          String v = (String) getSelectedValue() ;
          e.startDrag(DragSource.DefaultCopyDrop, new StringSelection(v), this) ;
     }or a variation on it. You will of course need the imports and such to support these, but most of it is in the java.awt.dnd package.
Then in your target you'll need a method to catch the drop ...
     public void drop(DropTargetDropEvent e){
          try{
               DataFlavor stringFlavor = DataFlavor.stringFlavor ;
               Transferable tr = e.getTransferable() ;
               if(e.isDataFlavorSupported(stringFlavor)){
                    String name = (String) tr.getTransferData(stringFlavor) ;
                    e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE) ;
                    Point p = e.getLocation() ;
                    int x = Integer.parseInt(String.valueOf(Math.round(p.getX()))) ;
                    int y = Integer.parseInt(String.valueOf(Math.round(p.getY()))) ;
                    int i = lastScenarioIndex++ ;
                    addDrawingObject(
                         new ScenarioDrawingObject("SCENARIO_" + i, "SCENARIO_" + i, y, x,
                         new SequenceMemberDrawingObject(name, name, 20, 20))) ;
                    resizeContainer() ;
          catch(IOException ioe){
               ioe.printStackTrace() ;
          catch(UnsupportedFlavorException ufe){
               ufe.printStackTrace() ;
     }There's a little more to it, but that's the crux of it.
Cheers.

Similar Messages

  • Is it possibiel to disable drag and drop of JTable columns?

    Hi,
    Using JDK6 I would like to disable user to drag and drop columns and change the default layout of my JTables.
    Thanks for any help,

    Using JDK6 I would like to disable user to drag and drop columns Read the JTableHeader API. You can prevent reordering of the columns.
    and change the default layout of my JTables.How do you expect us to answser this??? What do you mean by changing the layout? Whats wrong with row and column and what do you want to change it to?

  • Drag n Drop in JTable with AbstractTableModel

    Dear Experts,
    I would like to drag and drop rows in a JTable. For example, if I have 6 rows in a JTable based on an AbstractTableModel and if I am trying to drag row number 5 and wish to drop it at row number 2, then the 5th row which was dragged should be pasted as 3rd row and the rows 3 and 4 should be rearranged (ie, moved one place down).
    Can anyone help me in achieving this? Any readymade code available? :-)
    I tried running the code in the Java Tutorial in the link
    http://java.sun.com/docs/books/tutorial/uiswing/examples/dnd/index.html
    but, this didnt help as it was mainly for a DefaultTableModel I guess. Also, when I used the StringTransferHandler and TableTransferHandler, I was able achieve just copying the dragged row and pasting at the dropped row. The row rearrangement was not functioning.
    Pls Help...
    Thanks & Regards
    Irfaan

    I have 6 rows in a JTable based on an AbstractTableModelDo you know what "Abstract" means? I suggest you look it up in your Java text book.
    You are not using the AbstractTableModel, you are using a TableModel that extends AbstractTableModel.
    but, this didnt help as it was mainly for a DefaultTableModel That is exactly why you should be using the DefaultTableModel since it supports the concept of moving rows. If you want to use a custom TableModel, then you need to implement the concept of moving rows yourself. So why write a custom TableModel when this has already been done for you??

  • Drag n Drop In Jtable

    Hiii Guys......
    I need a code for drag n drop feature in JTable.
    i need that, i should be able to interchange value of two cells in the same Jtable with drag n drop..... with values getting changed in the database also......

    What code have you written so far?

  • Drag and Drop in JTable never gets DropTargetListener events

    I'm trying to implement Drag/Drop between two JTables. I have adapted the source from the Drag/Drop Tutorial but none of the DropTargetListener events get called. When I try to drag a row from one table to the other, the debug output is as follows:
    beginning drag : ROW 3
    dragsource : dragExit
    dragsource : dragDropEnd
    I'm using JDK 1.3. Any help would be appreciated, here is the source:
    public class DnDTable extends JTable implements DropTargetListener, DragSourceListener, DragGestureListener
    public DnDTable(Object[][] rowData,Object[] columnNames)
    super(rowData,columnNames);
    m_dropTarget = new DropTarget(this,this);
    m_dragSource = new DragSource();
    m_dragSource.createDefaultDragGestureRecognizer(this,DnDConstants.ACTION_MOVE,this);
    public void dragEnter(DropTargetDragEvent event)
    System.out.println("droptarget : dragEnter");
    event.acceptDrag(DnDConstants.ACTION_MOVE);
    public void dragExit(DropTargetEvent event)
    System.out.println("droptarget : dragExit");
    public void dragOver(DropTargetDragEvent event)
    System.out.println("droptarget : dragOver");
    public void drop(DropTargetDropEvent event)
    System.out.println("droptarget : drop");
    try
    Transferable transferable = event.getTransferable();
    // we accept only Strings
    if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor))
    event.acceptDrop(DnDConstants.ACTION_MOVE);
    String s = (String)transferable.getTransferData(DataFlavor.stringFlavor);
    setValueAt(s,rowAtPoint(event.getLocation()),0);
    event.getDropTargetContext().dropComplete(true);
    else
    event.rejectDrop();
    catch(IOException exception)
    exception.printStackTrace();
    System.err.println( "Exception" + exception.getMessage());
    event.rejectDrop();
    catch(UnsupportedFlavorException ufException )
    ufException.printStackTrace();
    System.err.println( "Exception" + ufException.getMessage());
    event.rejectDrop();
    public void dropActionChanged(DropTargetDragEvent e)
    public void dragGestureRecognized(DragGestureEvent event)
    int nDragRow;
    Object object;
    nDragRow = getSelectedRow();
    object = getValueAt(nDragRow,0);
    if (object != null )
    System.out.println("beginning drag:" + object.toString());
    StringSelection text = new StringSelection(object.toString());
    m_dragSource.startDrag(event,DragSource.DefaultMoveDrop,text,this);
    else
    System.out.println("nothing was selected");
    public void dragDropEnd(DragSourceDropEvent event)
    System.out.println("dragsource : dragDropEnd");
    public void dragEnter(DragSourceDragEvent event)
    System.out.println("dragsource : dragEnter");
    public void dragExit(DragSourceEvent event)
    System.out.println("dragsource : dragExit");
    public void dragOver(DragSourceDragEvent event)
    System.out.println("dragsource : dragOver");
    public void dropActionChanged(DragSourceDragEvent event)
    System.out.println("dragsource : dropActionChanged");
    DropTarget m_dropTarget;
    DragSource m_dragSource;

    Hi My friend,
    The code you have took will perfectly works.
    I have an option please try this.
    Instead of DnDConstants.ACTION_MOVE try DnDConstants.ACTION_COPY.
    Lakshmi.

  • Drag and Drop in jtable!

    Hi everybody!
    I want drag some element from some list and drop in some cell in jtable, but i have a problem because this element can use more than one cell, all depends! , the drag moviment seem to work fine between list and the JTable. when the drag cursor is above a row in the JTable, ONLY ONE cell in that row is highlighted, but i want that more than one cell get highlighted and i want put the information in more than one cell.
    Anyone know how to do that?
    thanks in advance
    ps:I am a freshman in foruns, sorry about my english.

    Hi everybody!
    I want drag some element from some list and drop in some cell in jtable, but i have a problem because this element can use more than one cell, all depends! , the drag moviment seem to work fine between list and the JTable. when the drag cursor is above a row in the JTable, ONLY ONE cell in that row is highlighted, but i want that more than one cell get highlighted and i want put the information in more than one cell.
    Anyone know how to do that?
    thanks in advance
    ps:I am a freshman in foruns, sorry about my english.

  • Multiple columns Drag n Drop in JTable

    Issue:
    I'm building a JTable with groupable column headers like this:
    GROUP A_ | GROUP B_
    col1 | col2 | col3 | col4
    I based this on the GroupableHeader example at: http://www2.gol.com/users/tame/swing/examples/JTableExamples1.html
    Question:
    How would I approach allowing the user to reorder Groups by dragging
    the Group level header(GROUP A_) and all of its subordinate columns (col1 and col2) and dropping into a new location. I'd like to simulate the standard JTable column DnD animation - but with groups of columns.

    Have you solved this problem ? I have the same question.

  • Drag and Drop inside JTable: what draws the 'insert' line during the drag?

    I'm trying to reconfigure a rather complex table with a fair number of custom renderers to include drag & drop of rows for resorting the table. Everything is working great, except that as I drag the rows there is no indication of the current insert point (i.e. the line that appears between rows). When I make a simpler table I see the line... I'm not sure what aspect of my current table is blocking this function. I'm writing in the hope that can someone can direct me to the method(s) responsible for drawing this line.
    Thanks!

    To elaborate a bit for anyone who might read this. I inquired with the Substance developers and they hope to support this feature in v5.1 (which requires SE6), but have no plans to update v4.3 (the last release before a switch to SE6).
    Also, I'd still be grateful for any info pointing me to the Swing methods that draw the drag line.

  • What does it take to drag and drop a jTable row to a jTextField?

    What kind of Listeners do I need? I have implemented transferListener and overrode createTransferable. But there was nothing responding when I tried to drag a row away. Any other Listener do I need to implement?

    For better help sooner, post an SSCCE.

  • Drag and Drop from JTable

    Using cntl C and cntl V to copy data from a JTable
    into another file
    j2sdk1.4.0 copied the column names along with the data.
    j2sdk1.4.1_04 does not copy the column names anymore.
    Is there any way to get the previous functionality?

    Does anyone use cut and paste to copy data from a JTable to another file?
    I wonder why the new RE-Version doesn't copy the column headers anymore.

  • How to outline selected cells during drag and drop in the jtable

    Hi,
    I have spent a lot of time to find out how to outline selected cells during drag in the jtable, but I did not find the answer.
    Can anybody give me a tip, where to read more about this problem or even better, give an example...
    I have the following situation:
    1.Table has 10 rows and 10 columns
    2.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION) and setCellSelectionEnabled(true)
    3.user select 5 cells in 4th row (for example cell45,cell46,cell47,cell48 and cell49)
    4.user starts dragging. During dragging an outline should be drawn. Outline should be a rectangular with width of 5 cells and height of one cell. Outline should move according to the mouse position.
    5.rectangular disappears when dropped
    Regards,
    Primoz

    In "createTransferable" you can create a drag image
    which you can paint in "dragOver" and clear in "drop" method of DropTarget :
    package dnd;
    * DragDropJTableCellContents.java
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    import java.awt.*;
    import java.awt.datatransfer.*;
    import java.awt.dnd.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    public class DragDropJTableCellContents extends JFrame {
        public DragDropJTableCellContents() {
            setTitle("Drag and Drop JTable");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getContentPane().add(createTable("JTable"), BorderLayout.CENTER);
            setSize(400, 300);
            setLocationRelativeTo(null);
        private JPanel createTable(String tableId) {
            DefaultTableModel model = new DefaultTableModel();
            for (int i = 0; i < 10; i++) {
                model.addColumn("Column "+i);
            for (int i = 0; i < 10; i++) {
                String[] rowData = new String[10];
                for (int j = 0; j < 10; j++) {
                    rowData[j] = tableId + " " + i + j;
                model.addRow(rowData);
            JTable table = new JTable(model);
            table.getTableHeader().setReorderingAllowed(false);
            table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
            table.setCellSelectionEnabled(true);
            JScrollPane scrollPane = new JScrollPane(table);
            table.setDragEnabled(true);
            TableTransferHandler th = new TableTransferHandler();
            table.setTransferHandler(th);
            table.setDropTarget(new TableDropTarget(th));
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(scrollPane);
            panel.setBorder(BorderFactory.createTitledBorder(tableId));
            return panel;
        public static void main(String[] args) {
            new DragDropJTableCellContents().setVisible(true);
        abstract class StringTransferHandler extends TransferHandler {
            public int dropAction;
            protected abstract String exportString(JComponent c);
            protected abstract void importString(JComponent c, String str);
            @Override
            protected Transferable createTransferable(JComponent c) {
                return new StringSelection(exportString(c));
            @Override
            public int getSourceActions(JComponent c) {
                return COPY;
            @Override
            public boolean importData(JComponent c, Transferable t) {
                if (canImport(c, t.getTransferDataFlavors())) {
                    try {
                        String str = (String) t.getTransferData(DataFlavor.stringFlavor);
                        importString(c, str);
                        return true;
                    } catch (UnsupportedFlavorException ufe) {
                    } catch (IOException ioe) {
                return false;
            @Override
            public boolean canImport(JComponent c, DataFlavor[] flavors) {
                for (int ndx = 0; ndx < flavors.length; ndx++) {
                    if (DataFlavor.stringFlavor.equals(flavors[ndx])) {
                        return true;
                return false;
        class TableTransferHandler extends StringTransferHandler {
            private int dragRow;
            private int[] dragColumns;
            private BufferedImage[] image;
            private int row;
            private int[] columns;
            public JTable target;
            @Override
            protected Transferable createTransferable(JComponent c) {
                JTable table = (JTable) c;
                dragRow = table.getSelectedRow();
                dragColumns = table.getSelectedColumns();
                createDragImage(table);
                return new StringSelection(exportString(c));
            protected String exportString(JComponent c) {
                JTable table = (JTable) c;
                row = table.getSelectedRow();
                columns = table.getSelectedColumns();
                StringBuffer buff = new StringBuffer();
                for (int j = 0; j < columns.length; j++) {
                    Object val = table.getValueAt(row, columns[j]);
                    buff.append(val == null ? "" : val.toString());
                    if (j != columns.length - 1) {
                        buff.append(",");
                return buff.toString();
            protected void importString(JComponent c, String str) {
                target = (JTable) c;
                DefaultTableModel model = (DefaultTableModel) target.getModel();
                String[] values = str.split("\n");
                int colCount = target.getSelectedColumn();
                int max = target.getColumnCount();
                for (int ndx = 0; ndx < values.length; ndx++) {
                    String[] data = values[ndx].split(",");
                    for (int i = 0; i < data.length; i++) {
                        String string = data;
    if(colCount < max){
    model.setValueAt(string, target.getSelectedRow(), colCount);
    colCount++;
    public BufferedImage[] getDragImage() {
    return image;
    private void createDragImage(JTable table) {
    if (dragColumns != null) {
    try {
    image = new BufferedImage[dragColumns.length];
    for (int i = 0; i < dragColumns.length; i++) {
    Rectangle cellBounds = table.getCellRect(dragRow, i, true);
    TableCellRenderer r = table.getCellRenderer(dragRow, i);
    DefaultTableModel m = (DefaultTableModel) table.getModel();
    JComponent lbl = (JComponent) r.getTableCellRendererComponent(table,
    table.getValueAt(dragRow, dragColumns[i]), false, false, dragRow, i);
    lbl.setBounds(cellBounds);
    BufferedImage img = new BufferedImage(lbl.getWidth(), lbl.getHeight(),
    BufferedImage.TYPE_INT_ARGB_PRE);
    Graphics2D graphics = img.createGraphics();
    graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
    lbl.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
    lbl.paint(graphics);
    graphics.dispose();
    image[i] = img;
    } catch (RuntimeException re) {
    class TableDropTarget extends DropTarget {
    private Insets autoscrollInsets = new Insets(20, 20, 20, 20);
    private Rectangle rect2D = new Rectangle();
    private TableTransferHandler handler;
    public TableDropTarget(TableTransferHandler h) {
    super();
    this.handler = h;
    @Override
    public void dragOver(DropTargetDragEvent dtde) {
    handler.dropAction = dtde.getDropAction();
    JTable table = (JTable) dtde.getDropTargetContext().getComponent();
    Point location = dtde.getLocation();
    int row = table.rowAtPoint(location);
    int column = table.columnAtPoint(location);
    table.changeSelection(row, column, false, false);
    paintImage(table, location);
    autoscroll(table, location);
    super.dragOver(dtde);
    public void dragExit(DropTargetDragEvent dtde) {
    clearImage((JTable) dtde.getDropTargetContext().getComponent());
    super.dragExit(dtde);
    @Override
    public void drop(DropTargetDropEvent dtde) {
    Transferable data = dtde.getTransferable();
    JTable table = (JTable) dtde.getDropTargetContext().getComponent();
    clearImage(table);
    handler.importData(table, data);
    super.drop(dtde);
    private final void paintImage(JTable table, Point location) {
    Point pt = new Point(location);
    BufferedImage[] image = handler.getDragImage();
    if (image != null) {
    table.paintImmediately(rect2D.getBounds());
    rect2D.setLocation(pt.x - 15, pt.y - 15);
    int wRect2D = 0;
    int hRect2D = 0;
    for (int i = 0; i < image.length; i++) {
    table.getGraphics().drawImage(image[i], pt.x - 15, pt.y - 15, table);
    pt.x += image[i].getWidth();
    if (hRect2D < image[i].getHeight()) {
    hRect2D = image[i].getHeight();
    wRect2D += image[i].getWidth();
    rect2D.setSize(wRect2D, hRect2D);
    private final void clearImage(JTable table) {
    table.paintImmediately(rect2D.getBounds());
    private Insets getAutoscrollInsets() {
    return autoscrollInsets;
    private void autoscroll(JTable table, Point cursorLocation) {
    Insets insets = getAutoscrollInsets();
    Rectangle outer = table.getVisibleRect();
    Rectangle inner = new Rectangle(outer.x + insets.left,
    outer.y + insets.top,
    outer.width - (insets.left + insets.right),
    outer.height - (insets.top + insets.bottom));
    if (!inner.contains(cursorLocation)) {
    Rectangle scrollRect = new Rectangle(cursorLocation.x - insets.left,
    cursorLocation.y - insets.top,
    insets.left + insets.right,
    insets.top + insets.bottom);
    table.scrollRectToVisible(scrollRect);
    Edited by: Andre_Uhres on Nov 18, 2007 10:03 PM

  • Must click then click and drag for JTable Drag and Drop

    Hi All,
    I've been using Java 1.4 to drag and drop data between two tables in our application. Basically I need to drag the data from individual rows of the source table and insert it into one of the cells in the new table. This works absolutely fine and has made a huge improvement to this portion of our app. I've included example source code below that does a similar thing by transferring data from one table and inserting it into another (it's quite big and also not as well done as the example in our real app but unfortunately I can't send the source for that).
    The thing I've noticed though is that in order to start dragging data I need to click to select it and then press and hold the mouse button to start dragging, whereas under W**dows and just about every other OS you can just press and hold and start dragging straight away. If you try this with a JTable though it just changes the rows you have selected so the drag and drop works but feels a bit clunky and amateurish. I'd like to do something about this such that it works like Windows Explorer (or similar) where you can just press the mouse button and start dragging.
    Any help would be greatly appreciated - and if anybody finds the code useful you're more than welcome to it. Note that the business end of this is CustomTransferHandler.java - this will show you how to insert data at a specific position in a JTable, it's a bit of a faff but not too bad once you've got it sussed.
    Thanks,
    Bart Read
    ===============================================================
    TestFrame.java
    * TestFrame.java
    * Created on October 21, 2002, 4:59 PM
    import java.awt.*;
    import java.awt.datatransfer.*;
    import java.awt.dnd.*;
    import java.awt.event.*;
    import java.util.TooManyListenersException;
    import javax.swing.*;
    * @author  readb
    public class TestFrame extends javax.swing.JFrame
         private static final String [] NAMES     = {
              "John", "Geoff", "Madeleine", "Maria", "Flanders",
              "Homer", "Marge", "Bart", "Lisa", "Weird Baby" };
         private JTable source;
         private JTable dest;
         private MyTableModel     sourceModel;
         private MyTableModel     destModel;
         private Clipboard          clipboard;
         /** Creates a new instance of TestFrame */
         public TestFrame()
              clipboard = getToolkit().getSystemClipboard();
              Container c = getContentPane();
              c.setLayout( new BorderLayout( 40, 40 ) );
              source = new MyJTable();
              sourceModel = new MyTableModel();
              source.setModel( sourceModel );
              source.setDragEnabled( true );
              CustomTransferHandler handler = new CustomTransferHandler( "Source handler" );
              source.setTransferHandler( handler );
              try
                   source.getDropTarget().addDropTargetListener( handler );
              catch ( TooManyListenersException tmle )
                   tmle.printStackTrace();
              dest = new MyJTable();
              destModel = new MyTableModel();
              dest.setModel( destModel );
              dest.setDragEnabled( true );
              handler = new CustomTransferHandler( "Dest handler" );
              dest.setTransferHandler( handler );
              try
                   dest.getDropTarget().addDropTargetListener( handler );
              catch ( TooManyListenersException tmle )
                   tmle.printStackTrace();
              c.add( new JScrollPane( source ), BorderLayout.WEST );
              c.add( new JScrollPane( dest ), BorderLayout.EAST );
              populate();
         private void populate( MyTableModel model )
              for ( int index = 0; index < NAMES.length; ++index )
                   model.setRow( index, new DataRow( index + 1, NAMES[ index ] ) );
         private void populate()
              populate( sourceModel );
              populate( destModel );
         public static void main( String [] args )
              TestFrame app = new TestFrame();
              app.addWindowListener(
                   new WindowAdapter() {
                        public void windowClosing( WindowEvent we )
                             System.exit( 0 );
              app.pack();
              app.setSize( 1000, 600 );
              app.show();
         private class MyJTable extends JTable
              public boolean getScrollableTracksViewportHeight()
                   Component parent = getParent();
                   if (parent instanceof JViewport)
                        return parent.getHeight() > getPreferredSize().height;
                   return false;
    }=====================================================================
    MyTableModel.java
    * MyTableModel.java
    * Created on October 21, 2002, 4:43 PM
    import java.util.ArrayList;
    * @author  readb
    public class MyTableModel extends javax.swing.table.AbstractTableModel
         private static final int          NUMBER               = 0;
         private static final int          NAME               = 1;
         private static final String []     COLUMN_HEADINGS     = { "Number", "Name" };
         private ArrayList data;
         /** Creates a new instance of MyTableModel */
         public MyTableModel()
              super();
              data = new ArrayList();
         public int getColumnCount()
              return COLUMN_HEADINGS.length;
         public String getColumnName( int index )
              return COLUMN_HEADINGS[ index ];
         public Class getColumnClass( int index )
              switch ( index )
                   case NUMBER:
                        return Integer.class;
                   case NAME:
                        return String.class;
                   default:
                        throw new IllegalArgumentException( "Illegal column index: " + index );
         public int getRowCount()
              return ( null == data ? 0 : data.size() );
         public Object getValueAt( int row, int column )
              DataRow dataRow = ( DataRow ) data.get( row );
              switch ( column )
                   case NUMBER:
                        return new Integer( dataRow.getNumber() );
                   case NAME:
                        return dataRow.getName();
                   default:
                        throw new IllegalArgumentException( "Illegal column index: " + column );
         public void addRow( DataRow row )
              int rowIndex = data.size();
              data.add( row );
              fireTableRowsInserted( rowIndex, rowIndex );
         public void addRows( DataRow [] rows )
              int firstRow = data.size();
              for ( int index = 0; index < rows.length; ++index )
                   data.add( rows[ index ] );
              fireTableRowsInserted( firstRow, data.size() - 1 );
         public void setRow( int index, DataRow row )
              if ( index == data.size() )
                   data.add( row );
              else
                   data.set( index, row );
              fireTableRowsUpdated( index, index );
         public void insertRows( int index, DataRow [] rows )
              for ( int rowIndex = rows.length - 1; rowIndex >= 0; --rowIndex )
                   data.add( index, rows[ rowIndex ] );
              fireTableRowsInserted( index, index + rows.length - 1 );
         public DataRow getRow( int index )
              return ( DataRow ) data.get( index );
         public DataRow removeRow( int index )
              DataRow retVal = ( DataRow ) data.remove( index );
              fireTableRowsDeleted( index, index );
              return retVal;
         public boolean removeRow( DataRow row )
              int index = data.indexOf( row );
              boolean retVal = data.remove( row );
              fireTableRowsDeleted( index, index );
              return retVal;
         public void removeRows( DataRow [] rows )
              for ( int index = 0; index < rows.length; ++index )
                   data.remove( rows[ index ] );
              fireTableDataChanged();
    }=====================================================================
    DataRow.java
    * DataRow.java
    * Created on October 21, 2002, 4:41 PM
    import java.io.Serializable;
    * @author  readb
    public class DataRow implements Serializable
         private int          number;
         private String     name;
         /** Creates a new instance of DataRow */
         public DataRow( int number, String name )
              this.number = number;
              this.name = name;
         public int getNumber()
              return number;
         public String getName()
              return name;
         public String toString()
              return String.valueOf( number ) + ": " + name;
    }======================================================================
    CustomTransferHandler.java
    * CustomTransferHandler.java
    * Created on October 22, 2002, 8:36 AM
    import java.awt.*;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.ClipboardOwner;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.dnd.*;
    import java.awt.event.InputEvent;
    import java.io.IOException;
    import java.util.Arrays;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JComponent;
    import javax.swing.JTable;
    import javax.swing.TransferHandler;
    * @author  readb
    public class CustomTransferHandler
                   extends TransferHandler
                   implements Transferable, ClipboardOwner, DropTargetListener
         public static final DataFlavor     ROW_ARRAY_FLAVOR     = new DataFlavor( DataRow[].class, "Multiple rows of data" );
         private String               name;
         private ImageIcon          myIcon;
         private     DataRow []          data;
         private boolean               clipboardOwner                    = false;
         private int                    rowIndex                         = -1;
         /** Creates a new instance of CustomTransferHandler */
         public CustomTransferHandler( String name )
              this.name = name;
         public boolean canImport( JComponent comp, DataFlavor [] transferFlavors )
              System.err.println( "CustomTransferHandler::canImport" );
              if ( comp instanceof JTable && ( ( JTable ) comp ).getModel() instanceof MyTableModel )
                   for ( int index = 0; index < transferFlavors.length; ++index )
                        if ( ! transferFlavors[ index ].equals( ROW_ARRAY_FLAVOR ) )
                             return false;
                   return true;
              else
                   return false;
         protected Transferable createTransferable( JComponent c )
              System.err.println( "CustomTransferHandler::createTransferable" );
              if ( ! ( c instanceof JTable ) || ! ( ( ( JTable ) c ).getModel() instanceof MyTableModel ) )
                   return null;
              this.data = null;
              JTable               table     = ( JTable ) c;
              MyTableModel     model     = ( MyTableModel ) table.getModel();
              Clipboard          cb          = table.getToolkit().getSystemClipboard();
              cb.setContents( this, this );
              clipboardOwner = true;
              int [] selectedRows = table.getSelectedRows();
              Arrays.sort( selectedRows );
              data = new DataRow[ selectedRows.length ];
              for ( int index = 0; index < data.length; ++index )
                   data[ index ] = model.getRow( selectedRows[ index ] );
              return this;
         public void exportAsDrag( JComponent comp, InputEvent e, int action )
              super.exportAsDrag( comp, e, action );
              Clipboard          cb          = comp.getToolkit().getSystemClipboard();
              cb.setContents( this, this );
         protected void exportDone( JComponent source, Transferable data, int action )
              System.err.println( "CustomTransferHandler::exportDone" );
              if ( TransferHandler.MOVE == action && source instanceof JTable && ( ( JTable ) source ).getModel() instanceof MyTableModel )
                   JTable table = ( JTable ) source;
                   MyTableModel model = ( MyTableModel ) table.getModel();
                   int [] selected = table.getSelectedRows();
                   for ( int index = selected.length - 1; index >= 0; --index )
                        model.removeRow( selected[ index ] );
         public void exportToClipboard( JComponent comp, Clipboard clip, int action )
              System.err.println( "CustomTransferHandler::exportToClipboard" );
         public int getSourceActions( JComponent c )
              System.err.println( "CustomTransferHandler::getSourceActions" );
              if ( ( c instanceof JTable ) && ( ( JTable ) c ).getModel() instanceof MyTableModel )
                   return MOVE;
              else
                   return NONE;
          *     I've commented this out because it doesn't appear to work in any case.
          *     The image isn't null but as far as I can tell this method is never
          *     invoked.
    //     public Icon getVisualRepresentation( Transferable t )
    //          System.err.println( "CustomTransferHandler::getVisualRepresentation" );
    //          if ( t instanceof CustomTransferHandler )
    //               if ( null == myIcon )
    //                    try
    //                         myIcon = new ImageIcon( getClass().getClassLoader().getResource( "dragimage.gif" ) );
    //                    catch ( Exception e )
    //                         System.err.println( "CustomTransferHandler::getVisualRepresentation: exception loading image" );
    //                         e.printStackTrace();
    //                    if ( null == myIcon )
    //                         System.err.println( "CustomTransferHandler::getVisualRepresentation: myIcon is still NULL" );
    //               return myIcon;
    //          else
    //               return null;
         public boolean importData( JComponent comp, Transferable t )
              System.err.println( "CustomTransferHandler::importData" );
              super.importData( comp, t );
              if ( ! ( comp instanceof JTable ) )
                   return false;
              if ( ! ( ( ( JTable ) comp ).getModel() instanceof MyTableModel ) )
                   return false;
              if ( clipboardOwner )
                   return false;
              if ( !t.isDataFlavorSupported( ROW_ARRAY_FLAVOR ) )
                   return false;
              try
                   data = ( DataRow [] ) t.getTransferData( ROW_ARRAY_FLAVOR );
                   return true;
              catch ( IOException ioe )
                   data = null;
                   return false;
              catch ( UnsupportedFlavorException ufe )
                   data = null;
                   return false;
         public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
              System.err.println( "MyTransferable::getTransferData" );
              if ( flavor.equals( ROW_ARRAY_FLAVOR ) )
                   return data;
              else
                   throw new UnsupportedFlavorException( flavor );
         public DataFlavor[] getTransferDataFlavors()
              System.err.println( "MyTransferable::getTransferDataFlavors" );
              DataFlavor [] flavors = new DataFlavor[ 1 ];
              flavors[ 0 ] = ROW_ARRAY_FLAVOR;
              return flavors;
         public boolean isDataFlavorSupported( DataFlavor flavor )
              System.err.println( "MyTransferable::isDataFlavorSupported" );
              return flavor.equals( ROW_ARRAY_FLAVOR );
         public void lostOwnership( Clipboard clipboard, Transferable transferable )
              clipboardOwner = false;
         /** Called while a drag operation is ongoing, when the mouse pointer enters
          * the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dragEnter(DropTargetDragEvent dtde)
         /** Called while a drag operation is ongoing, when the mouse pointer has
          * exited the operable part of the drop site for the
          * <code>DropTarget</code> registered with this listener.
          * @param dte the <code>DropTargetEvent</code>
         public void dragExit(DropTargetEvent dte)
         /** Called when a drag operation is ongoing, while the mouse pointer is still
          * over the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dragOver(DropTargetDragEvent dtde)
         /** Called when the drag operation has terminated with a drop on
          * the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * <p>
          * This method is responsible for undertaking
          * the transfer of the data associated with the
          * gesture. The <code>DropTargetDropEvent</code>
          * provides a means to obtain a <code>Transferable</code>
          * object that represents the data object(s) to
          * be transfered.<P>
          * From this method, the <code>DropTargetListener</code>
          * shall accept or reject the drop via the
          * acceptDrop(int dropAction) or rejectDrop() methods of the
          * <code>DropTargetDropEvent</code> parameter.
          * <P>
          * Subsequent to acceptDrop(), but not before,
          * <code>DropTargetDropEvent</code>'s getTransferable()
          * method may be invoked, and data transfer may be
          * performed via the returned <code>Transferable</code>'s
          * getTransferData() method.
          * <P>
          * At the completion of a drop, an implementation
          * of this method is required to signal the success/failure
          * of the drop by passing an appropriate
          * <code>boolean</code> to the <code>DropTargetDropEvent</code>'s
          * dropComplete(boolean success) method.
          * <P>
          * Note: The data transfer should be completed before the call  to the
          * <code>DropTargetDropEvent</code>'s dropComplete(boolean success) method.
          * After that, a call to the getTransferData() method of the
          * <code>Transferable</code> returned by
          * <code>DropTargetDropEvent.getTransferable()</code> is guaranteed to
          * succeed only if the data transfer is local; that is, only if
          * <code>DropTargetDropEvent.isLocalTransfer()</code> returns
          * <code>true</code>. Otherwise, the behavior of the call is
          * implementation-dependent.
          * <P>
          * @param dtde the <code>DropTargetDropEvent</code>
         public void drop(DropTargetDropEvent dtde)
              System.err.println( "CustomTransferHandler::drop" );
              Component c = dtde.getDropTargetContext().getDropTarget().getComponent();
              if ( ! ( c instanceof JComponent ) )
                   dtde.rejectDrop();
                   return;
              JComponent comp = ( JComponent ) c;
              if ( ! ( c instanceof JTable ) || ! ( ( ( JTable ) c ).getModel() instanceof MyTableModel ) )
                   dtde.rejectDrop();
                   return;
              dtde.acceptDrop( TransferHandler.MOVE );
              //     THIS is such a mess -- you can't do the following because
              //     getTransferable() throws an (undocumented) exception - what's that
              //     all about.
    //          Transferable t = dtde.getTransferable();
    //               if ( !t.isDataFlavourSupported( ROW_ARRAY_FLAVOR ) )
    //                    dtde.rejectDrop();
    //                    return false;
    //          TransferHandler handler = comp.getTransferHandler();
    //          if ( null == handler || ! handler.importData( comp, t ) )
    //               dtde.rejectDrop();
    //               return;
              Point p = dtde.getLocation();
              JTable table = ( JTable ) comp;
              rowIndex = table.rowAtPoint( p );
              //     So you have to do this instead and use the data that's been
              //     stored in the data member via import data.  Total mess.
              if ( null == data )
                   dtde.rejectDrop();
                   return;
              MyTableModel model = ( MyTableModel ) table.getModel();
              if ( rowIndex == -1 )
                   model.addRows( data );
              else
                   model.insertRows( rowIndex, data );
              dtde.acceptDrop( TransferHandler.MOVE );
         /** Called if the user has modified
          * the current drop gesture.
          * <P>
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dropActionChanged(DropTargetDragEvent dtde)
    }

    Hi again,
    Well I've tried using the MouseListener / MouseMotionListener approach but it doesn't quite seem to work, although it does get the events correctly. I think the reason is that it doesn't interact correctly with the Java DnD machinery which is something that V.V hinted at. It's something that I may need to look into if / when I have more time available.
    I have to say though that I haven't had any problems with scrollbars - we're making fairly heavy use of large tables and if you drag over a table with a scroll bar and move to the top or bottom then it scrolls as you would expect and allows you to drop the data where you like. For this situation I've used pretty much the same approach as for the toy example above except that I've implemented separate source and destination TransferHandlers (the source table is read-only, and it really doesn't make sense to allow people to drag from the destination table so I've essentially split the functionality of the example handler down the middle).
    I'm not actually particularly in favour of messing too much with the mechanics of DnD, more because of lack of time than anything else. Guess I'll just have to put up with this for the moment. Doesn't help that DnD is so poorly documented by Sun.
    Thanks for all your help.
    Bart

  • Drag and Drop in a JTable (ContentTable)

    Hello Friends,
    I am designing a tool which can be used for daily task distribution, according to time (as we setup in a outlook calendar) using JTable.
    Now I am planning to use a Drag and Drop option where in the task from "one date and time" can be moved to "another date and time" i.e row/column.
    E.g : Suppose the new task which is scheduled at 12:30pm on 22/03/07 has to be rescheduled at 3:00pm 26/03/07. The drag and drop should automatically recognise.
    It would be greate if anyone can throw in thier ideas.. 10 DUKE points..
    Thanks and Rgds,
    Pradeep

    Here's an example of drag and drop of a cell in JTable.
    You can move or copy (using Ctrl) a cell to another location:
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.StringSelection;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.io.IOException;
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.ListSelectionModel;
    import javax.swing.TransferHandler;
    import javax.swing.table.DefaultTableModel;
    public class DnD_Demo extends JFrame {
        public DnD_Demo() {
            setTitle("DnD Demo (Version 3)");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel = new JPanel(new GridLayout(1,1));
            panel.add(createTable("Table A"));
            getContentPane().add(panel,BorderLayout.CENTER);
            pack();
        private JPanel createTable(String tableId) {
            DefaultTableModel model = new DefaultTableModel();
            model.addColumn("Column 0");
            model.addColumn("Column 1");
            model.addColumn("Column 2");
            model.addColumn("Column 3");
            model.addRow(new String[]{tableId+" 00", tableId+" 01", tableId+" 02", tableId+" 03"});
            model.addRow(new String[]{tableId+" 10", tableId+" 11", tableId+" 12", tableId+" 13"});
            model.addRow(new String[]{tableId+" 20", tableId+" 21", tableId+" 22", tableId+" 23"});
            model.addRow(new String[]{tableId+" 30", tableId+" 31", tableId+" 32", tableId+" 33"});
            JTable table = new JTable(model);
            table.getTableHeader().setReorderingAllowed(false);
            table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setPreferredSize(new Dimension(400,100));
            table.setDragEnabled(true);
            table.setTransferHandler(new TableTransferHandler());
            JPanel panel = new JPanel();
            panel.add(scrollPane);
            panel.setBorder(BorderFactory.createTitledBorder(tableId));
            return panel;
        public static void main(String[] args) {
            new DnD_Demo().setVisible(true);
        abstract class StringTransferHandler extends TransferHandler {
            protected abstract String exportString(JComponent c);
            protected abstract void importString(JComponent c, String str);
            protected abstract void cleanup(JComponent c, boolean remove);
            protected Transferable createTransferable(JComponent c) {
                return new StringSelection(exportString(c));
            public int getSourceActions(JComponent c) {
                return COPY_OR_MOVE;
            public boolean importData(JComponent c, Transferable t) {
                if (canImport(c, t.getTransferDataFlavors())) {
                    try {
                        String str = (String)t.getTransferData(DataFlavor.stringFlavor);
                        importString(c, str);
                        return true;
                    } catch (UnsupportedFlavorException ufe) {
                    } catch (IOException ioe) {
                return false;
            protected void exportDone(JComponent c, Transferable data, int action) {
                cleanup(c, action == MOVE);
            public boolean canImport(JComponent c, DataFlavor[] flavors) {
                for (int i = 0; i < flavors.length; i++) {
                    if (DataFlavor.stringFlavor.equals(flavors)) {
    return true;
    return false;
    class TableTransferHandler extends StringTransferHandler {
    public JTable target;
    public int row = -1;
    public int col = -1;
    protected String exportString(JComponent c) {
    JTable table = (JTable)c;
    row = table.getSelectedRow();
    col = table.getSelectedColumn();
    return table.getValueAt(row, col).toString();
    protected void importString(JComponent c, String str) {
    target = (JTable)c;
    int row = target.getSelectedRow();
    int col = target.getSelectedColumn();
    target.getModel().setValueAt(str, row, col);
    protected void cleanup(JComponent c, boolean remove) {
    JTable table = (JTable)c;
    if (remove)
    table.getModel().setValueAt("", row, col);
    Message was edited by:
    Rodney_McKay

  • Drag and Drop between two JTables

    I tried to implement drag and drop between two JTables using data transfer, but i did not get it to work, that dnd works in both directions. i have my own transferhandler, but if is use setTransferHandler(handler), i'm no longer able to start a drag from that table. i also tried to use a mouse listener to call exportAsDrag, but i only works in one direction. any ideas or examples?

    That is a rather large request, and indicates that you have likely not spent much time researching the subject before posting. Read up on Swing drag & drop here (http://java.sun.com/docs/books/tutorial/dnd/), then ask specific questions about something you don't understand, problems with your implementation, etc.
    Mike

  • Drag and drop from/to JTable

    Hi,
    I am trying to implement drag and drop between two JTables. I have two questions about this and I hope you can help me.
    1. I would like to prevent the user from droping an Object in the same JTable as the object came from in the first place. How can I do that?
    2. How can I drop an Object in a JTable if there isn�t any rows in the table?
    I am using jdk 1.4.
    Thanks!!!
    :-)Lisa

    I think you just use setDragEnabled(true) on both tables.
    If not, then maybe this link will help:
    http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html

Maybe you are looking for