[Schmitzm-commits] r2153 - in trunk/schmitzm-core/src/main/java/de/schmitzm/swing: . dnd

scm-commit at wald.intevation.org scm-commit at wald.intevation.org
Sat Dec 8 18:06:18 CET 2012


Author: mojays
Date: 2012-12-08 18:06:18 +0100 (Sat, 08 Dec 2012)
New Revision: 2153

Added:
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListDropTargetListener.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListTransferHandler.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableDropTargetListener.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableTransferHandler.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingDropTargetListener.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingTransferHandler.java
Log:
ListingTransferHandler, JListTransferHandler, JTableTransferHandler: Generic drag and drop implementation between tables and lists

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListDropTargetListener.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListDropTargetListener.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListDropTargetListener.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.awt.Point;
+import java.awt.dnd.DropTargetListener;
+
+import javax.swing.JList;
+import javax.swing.ListModel;
+
+/**
+ * {@link DropTargetListener} for {@link JList}. Sub classes only have to
+ * implement {@link #addListItems(int)} to insert the dropped items into
+ * the individual {@link ListModel}.
+ * @author Martin O.J. Schmitz
+ * 
+ * @deprecated Simple but not reliable implementation. Use {@link JListTransferHandler}
+ *             instead
+ */
+public abstract class JListDropTargetListener extends ListingDropTargetListener<JList> {
+
+  /**
+   * Creates a new {@link DropTargetListener}.
+   * @param dropList table which acts as drop destination
+   */
+  public JListDropTargetListener(JList dropList) {
+    super(dropList);
+  }
+
+  /**
+   * Converts a location (relatively to {@link #dropListingComp}) to
+   * list index.
+   * @param loc location
+   * @see JList#locationToIndex(Point)
+   */
+  @Override
+  public int convertLocationToListIndex(Point loc) {
+    return getDropListingComponent().locationToIndex( loc );
+  }
+
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListTransferHandler.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListTransferHandler.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JListTransferHandler.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.swing.DropMode;
+import javax.swing.JList;
+import javax.swing.TransferHandler;
+
+/**
+ * {@link ListingTransferHandler} implementation for {@link JList}.
+ * Implementations only have to implement {@link #reorderListItems(JList, int[], int, int)}
+ * and {@link #moveListItems(JList, int[], int, JList, int)}.
+ * @author Martin O.J. Schmitz
+ *
+ */
+public abstract class JListTransferHandler extends ListingTransferHandler<JList> {
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JList} with drag
+   * and drop within the same list component (reorder) is NOT allowed..
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JListTransferHandler(JList... listComp) {
+    super(listComp);
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JList} with drag
+   * and drop within the same list component (reorder) is NOT allowed..
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JListTransferHandler(Collection<JList> listComp) {
+    super(listComp);
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JList}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JListTransferHandler(boolean innerListDragAllowed, JList... listComp) {
+    super(innerListDragAllowed, Arrays.asList(listComp) );
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JList}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JListTransferHandler(boolean innerListDragAllowed, Collection<JList> listComp) {
+    super(innerListDragAllowed,listComp);
+  }    
+  
+  /**
+   * Simply calls {@link JList#getSelectedIndices()}.
+   */
+  @Override
+  protected int[] getSelectedRows(JList listComp) {
+    return listComp.getSelectedIndices();
+  }
+
+  /**
+   * Simply calls {@link JList#getSelectedIndex()}.
+   */
+  @Override
+  protected int getSelectedRow(JList listComp) {
+    return listComp.getSelectedIndex();
+  }
+
+  /**
+   * Simply calls {@link JList#getSize()}.
+   */
+  @Override
+  protected int getRowCount(JList listComp) {
+    return listComp.getModel().getSize();
+  }
+  
+  
+  /**
+   * Treats the given drop location as {@link JList.DropLocation} and
+   * returns {@link JList.DropLocation#getIndex()}.
+   */
+  @Override
+  protected int getDropRow(JList listComp, DropLocation dl) {
+    int index = ((JList.DropLocation)dl).getIndex();
+    return index;
+  }
+
+  /**
+   * Simply calls {@link JList#setTransferHandler(TransferHandler)}. 
+   * @param listComp {@link JList} component
+   * @param transferHandler {@link TransferHandler} to be set (normally {@code this})
+   */
+  @Override
+  public void setTransferHandler(JList listComp, TransferHandler transferHandler) {
+    listComp.setTransferHandler(transferHandler);
+  }
+  
+  /**
+   * Simply calls {@link JList#getTransferHandler()()}. 
+   * @param listComp {@link JList} component
+   */
+  @Override
+  public TransferHandler getTransferHandler(JList listComp) {
+    return listComp.getTransferHandler();
+    
+  }
+
+  /**
+   * Simply calls {@link JList#setDropMode(DropMode)}. 
+   * @param listComp {@link JList} component
+   * @param dropMode {@link DropMode} to be set
+   */
+  @Override
+  public void setDropMode(JList listComp, DropMode dropMode) {
+    listComp.setDropMode(dropMode);
+  }
+  
+  /**
+   * Simply calls {@link JList#getDropMode()}. 
+   * @param listComp {@link JList} component
+   */
+  @Override
+  public DropMode getDropMode(JList listComp) {
+    return listComp.getDropMode();
+  }
+  
+  /**
+   * Simply calls {@link JList#setDragEnabled(boolean)}. 
+   * @param listComp {@link JList} component
+   * @param enabled  indicates whether drag is enabled
+   */
+  @Override
+  public void setDragEnabled(JList listComp, boolean enabled) {
+    listComp.setDragEnabled(enabled);
+  }
+  
+  /**
+   * Simply calls {@link JList#getDragEnabled()}. 
+   * @param listComp {@link JList} component
+   */
+  @Override
+  public boolean getDragEnabled(JList listComp) {
+    return listComp.getDragEnabled();
+  }
+
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableDropTargetListener.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableDropTargetListener.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableDropTargetListener.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.awt.Point;
+import java.awt.dnd.DropTargetListener;
+
+import javax.swing.JTable;
+import javax.swing.table.TableModel;
+
+/**
+ * {@link DropTargetListener} for {@link JTable}. Sub classes only have to
+ * implement {@link #addListItems(int)} to insert the dropped items into
+ * the individual {@link TableModel}.
+ * @author Martin O.J. Schmitz
+ *
+ * @deprecated Simple but not reliable implementation. Use {@link JTableTransferHandler}
+ *             instead
+ */
+public abstract class JTableDropTargetListener extends ListingDropTargetListener<JTable> {
+
+  /**
+   * Creates a new {@link DropTargetListener}.
+   * @param dropTable table which acts as drop destination
+   */
+  public JTableDropTargetListener(JTable dropTable) {
+    super(dropTable);
+  }
+
+  /**
+   * Converts a location (relatively to {@link #dropListingComp}) to
+   * table row.
+   * @param loc location
+   * @see JTable#rowAtPoint(Point)
+   */
+  @Override
+  public int convertLocationToListIndex(Point loc) {
+    return getDropListingComponent().rowAtPoint( loc );
+  }
+
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableTransferHandler.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableTransferHandler.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/JTableTransferHandler.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.swing.DropMode;
+import javax.swing.JTable;
+import javax.swing.TransferHandler;
+import javax.swing.table.TableModel;
+
+/**
+ * {@link ListingTransferHandler} implementation for {@link JTable} which
+ * means the drag and drop for <b>complete table rows</b>.
+ * Implementations only have to implement {@link #reorderListItems(JTable, int[], int, int)} and
+ * {@link #moveListItems(JTable, int[], int, JTable, int)}.
+ * @author Martin O.J. Schmitz
+ *
+ */
+public abstract class JTableTransferHandler extends ListingTransferHandler<JTable> {
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JTable} with drag
+   * and drop within the same list component (reorder) is NOT allowed..
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JTableTransferHandler(JTable... listComp) {
+    super(listComp);
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JTable} with drag
+   * and drop within the same list component (reorder) is NOT allowed..
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JTableTransferHandler(Collection<JTable> listComp) {
+    super(listComp);
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JTable}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JTableTransferHandler(boolean innerListDragAllowed, JTable... listComp) {
+    super(innerListDragAllowed, Arrays.asList(listComp) );
+  }
+
+  /**
+   * Creates new {@link ListingTransferHandler} for {@link JTable}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public JTableTransferHandler(boolean innerListDragAllowed, Collection<JTable> listComp) {
+    super(innerListDragAllowed,listComp);
+  }    
+  
+  /**
+   * Simply calls {@link JTable#getSelectedRows()}.
+   */
+  @Override
+  protected int[] getSelectedRows(JTable listComp) {
+    return listComp.getSelectedRows();
+  }
+
+  /**
+   * Simply calls {@link JTable#getSelectedRow()}.
+   */
+  @Override
+  protected int getSelectedRow(JTable listComp) {
+    return listComp.getSelectedRow();
+  }
+
+  /**
+   * Simply calls {@link TableModel#getRowCount()}.
+   */
+  @Override
+  protected int getRowCount(JTable listComp) {
+    return listComp.getModel().getRowCount();
+  }
+  
+  
+  /**
+   * Treats the given drop location as {@link JTable.DropLocation} and
+   * returns {@link JTable.DropLocation#getRow()}.
+   */
+  @Override
+  protected int getDropRow(JTable listComp, DropLocation dl) {
+    int index = ((JTable.DropLocation)dl).getRow();
+    return index;
+  }
+
+  /**
+   * Simply calls {@link JTable#setTransferHandler(TransferHandler)}. 
+   * @param listComp {@link JTable} component
+   * @param transferHandler {@link TransferHandler} to be set (normally {@code this})
+   */
+  @Override
+  public void setTransferHandler(JTable listComp, TransferHandler transferHandler) {
+    listComp.setTransferHandler(transferHandler);
+  }
+  
+  /**
+   * Simply calls {@link JTable#getTransferHandler()()}. 
+   * @param listComp {@link JTable} component
+   */
+  @Override
+  public TransferHandler getTransferHandler(JTable listComp) {
+    return listComp.getTransferHandler();
+    
+  }
+
+  /**
+   * Simply calls {@link JTable#setDropMode(DropMode)}. 
+   * @param listComp {@link JTable} component
+   * @param dropMode {@link DropMode} to be set
+   */
+  @Override
+  public void setDropMode(JTable listComp, DropMode dropMode) {
+    listComp.setDropMode(dropMode);
+  }
+  
+  /**
+   * Simply calls {@link JTable#getDropMode()}. 
+   * @param listComp {@link JTable} component
+   */
+  @Override
+  public DropMode getDropMode(JTable listComp) {
+    return listComp.getDropMode();
+  }
+  
+  /**
+   * Simply calls {@link JTable#setDragEnabled(boolean)}. 
+   * @param listComp {@link JTable} component
+   * @param enabled  indicates whether drag is enabled
+   */
+  @Override
+  public void setDragEnabled(JTable listComp, boolean enabled) {
+    listComp.setDragEnabled(enabled);
+  }
+  
+  /**
+   * Simply calls {@link JTable#getDragEnabled()}. 
+   * @param listComp {@link JTable} component
+   */
+  @Override
+  public boolean getDragEnabled(JTable listComp) {
+    return listComp.getDragEnabled();
+  }
+
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingDropTargetListener.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingDropTargetListener.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingDropTargetListener.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetListener;
+
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+
+import de.schmitzm.swing.JList;
+
+/**
+ * Abstract super class for several list drop targets ({@link JList} or {@link JTable}).
+ * 
+ * @author Martin O.J. Schmitz
+ * 
+ * @deprecated Simple but not reliable implementation. Use {@link ListingTransferHandler}
+ *             instead
+ */
+public abstract class ListingDropTargetListener<E extends Component> extends DropTargetAdapter {
+  /** Holds the list component (e.g. {@link JTable} or {@link JList})
+   *  which acts as destination for the dropped items. Not necessary the
+   *  drop component (which may be a {@link JScrollPane}). */
+  protected E dropListingComp;
+  
+  /**
+   * Creates a new {@link DropTargetListener}.
+   * @param dropListingComp list component (e.g. {@link JTable} or {@link JList})
+   *                        which acts as drop destination
+   */
+  public ListingDropTargetListener(E dropListingComp) {
+    super();
+    this.dropListingComp = dropListingComp;
+  }
+  
+  /**
+   * Performs the drop.
+   */
+  @Override
+  public void drop(DropTargetDropEvent dtde) {
+    Component dropComp = ((DropTarget)dtde.getSource()).getComponent();
+    Point dropLoc = dtde.getLocation();
+    Point dropLocOnTable = SwingUtilities.convertPoint(dropComp, dropLoc, dropListingComp);
+    
+    int row;
+    // if drop was above table, insert items at table head
+    if ( dropLocOnTable.y <= 0 )
+      row = 0;
+    else
+      // determine table row at drop location (-1 if drop was not on table)
+      row = convertLocationToListIndex( dropLocOnTable );
+
+    addListItems(row);
+  }
+  
+  /**
+   * Returns the list component (e.g. {@link JTable} or {@link JList})
+   * which acts as drop destination.
+   */
+  public E getDropListingComponent() {
+    return dropListingComp;
+  }
+  
+  /**
+   * Converts a location (relatively to {@link #dropListingComp}) to
+   * listing index.
+   * @param loc location
+   */
+  public abstract int convertLocationToListIndex(Point loc);
+
+  /**
+   * Adds items to the {@link #dropListingComp}. Which items (from drag source)
+   * must be inserted, the implementing class must determine itself,
+   * @param idx list index (or row) to add the items at
+   */
+  public abstract void addListItems(int idx);
+  
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingTransferHandler.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingTransferHandler.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/dnd/ListingTransferHandler.java	2012-12-08 17:06:18 UTC (rev 2153)
@@ -0,0 +1,380 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.dnd;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DragSource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.activation.DataHandler;
+import javax.swing.DropMode;
+import javax.swing.JComponent;
+import javax.swing.JList;
+import javax.swing.JTable;
+import javax.swing.TransferHandler;
+
+import org.apache.log4j.Logger;
+
+import de.schmitzm.lang.LangUtil;
+
+/**
+ * Abstract super class for {@link TransferHandler}, which implements drag & drop
+ * between one or more list components ({@link JTable}, {@link JList}, ...).
+ * For each of the list components
+ * <ul>
+ *   <li>this {@link TransferHandler} must be set</li>
+ *   <li>drag must be enabled, e.g. by {@link JList#setDragEnabled(boolean)}</li>
+ *   <li>drop mode must be set, e.g. by {@link JList#setDropMode(javax.swing.DropMode)}
+ * </ul>
+ * To allow drag and drop between all of the lists without any special restriction
+ * {@link #initializeLists()} can be called. Otherwise these properties must be set
+ * individually by the calling application class!
+ * @author Martin O.J. Schmitz
+ *
+ */
+public abstract class ListingTransferHandler<LIST_IMPL extends Component> extends TransferHandler {
+  protected Logger LOGGER = LangUtil.createLogger(this);
+  
+  private final DataFlavor localObjectFlavor = new DataFlavor(Integer.class, "Integer Row Index");
+
+  /** Hold the list components between which drag and drop is allowed */ 
+  protected ArrayList<LIST_IMPL>  dndListComp = null;
+  /** Holds the source component (the drag component) */
+  protected LIST_IMPL dragSourceComp = null;
+  /** Holds the destination component (the drop component) */
+  protected LIST_IMPL dropTargetComp = null;
+  /** Indicates whether drag and drop within the same list component is allowed (to
+   *  reorder the elements). */
+  protected boolean innerListDragAllowed = false;
+
+  
+  /**
+   * Creates new {@link TransferHandler} with drag and drop within the same list
+   * component (reorder) is NOT allowed.
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public ListingTransferHandler(LIST_IMPL... listComp) {
+    this(Arrays.asList(listComp));
+  }
+
+  /**
+   * Creates new {@link TransferHandler} with drag and drop within the same list
+   * component (reorder) is NOT allowed.
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public ListingTransferHandler(Collection<LIST_IMPL> listComp) {
+    this(false, listComp);
+  }
+
+  /**
+   * Creates new {@link TransferHandler}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public ListingTransferHandler(boolean innerListDragAllowed, LIST_IMPL... listComp) {
+    this(innerListDragAllowed, Arrays.asList(listComp) );
+  }
+
+  /**
+   * Creates new {@link TransferHandler}.
+   * @param innerListDragAllowed indicates whether drag and drop within the same list component
+   *                             is allowed (to reorder the elements)
+   * @param listComp list components between which drag and drop is allowed
+   */
+  public ListingTransferHandler(boolean innerListDragAllowed, Collection<LIST_IMPL> listComp) {
+    this.dndListComp = new ArrayList<LIST_IMPL>(listComp);
+    this.innerListDragAllowed = innerListDragAllowed;
+  }    
+  
+  /**
+   * For all list components this method
+   * <ul>
+   *   <li>set {@code this} as {@link TransferHandler}</li>
+   *   <li>enables drag by {@link #setDragEnabled(Component, boolean)</li>
+   *   <li>sets drop mode to {@link DropMode#INSERT} by {@link #setDropMode(Component, DropMode)}
+   * </ul>
+   */
+  public void initializeLists() {
+    for (LIST_IMPL listComp : dndListComp) {
+      setTransferHandler(listComp, this);
+      setDragEnabled(listComp, true);
+      setDropMode(listComp, DropMode.INSERT);
+    }
+  }
+  
+  /**
+   * For Debugging.
+   */
+  private void logCompIndex(String prefix, Component c) {
+    String mess = prefix+": "+ dndListComp.indexOf(c);
+    LOGGER.debug(mess);
+  }
+
+  /**
+   * Creates {@link Transferable} on drag start.
+   */
+  @Override
+  protected Transferable createTransferable(JComponent c) {
+     assert (dndListComp.contains(c));
+     return new DataHandler(getSelectedRow((LIST_IMPL)c), localObjectFlavor.getMimeType());
+  }
+
+  /**
+   * Checks whether drop is allowed to component.  
+   */
+  @Override
+  public boolean canImport(TransferSupport info) {
+     Component dropComp = info.getComponent();
+     logCompIndex("canImport", dropComp);
+     // Check if drop is allowed to destination component
+     boolean dndAllowed = ( isInnerListDragAllowed() || dropComp != getDragSource() ) &&
+                          dndListComp.contains(dropComp) &&
+                          checkDragDropAllowed(getDragSource(), (LIST_IMPL)dropComp) &&
+                          info.isDrop() && 
+                          info.isDataFlavorSupported(localObjectFlavor);
+     if ( dndAllowed ) {
+       // remember target component for easy access
+       this.dropTargetComp = (LIST_IMPL)dropComp;
+       // set cursor for possible drop
+       dropComp.setCursor( DragSource.DefaultMoveDrop );
+     } else
+       // set cursor for impossible drop
+       dropComp.setCursor( DragSource.DefaultMoveNoDrop );
+     
+     return dndAllowed;
+  }
+  
+  /**
+   * Checks whether drag and drop is allowed between two list components.
+   * This default implementation always returns {@code true}. Sub classes can
+   * override this method to implement special rules.
+   */
+  protected boolean checkDragDropAllowed(LIST_IMPL fromList, LIST_IMPL toList) {
+    return true;
+  }
+
+
+  /**
+   * Returns {@link TransferHandler#COPY_OR_MOVE}.
+   */
+  @Override
+  public int getSourceActions(JComponent c) {
+    logCompIndex("getSourceAction", c);
+    this.dragSourceComp = (LIST_IMPL)c;
+    return TransferHandler.COPY_OR_MOVE;
+  }
+
+  /**
+   * Performs the drop action.
+   */
+  @Override
+  public boolean importData(TransferHandler.TransferSupport info) {
+     LIST_IMPL target = (LIST_IMPL)info.getComponent();
+     LIST_IMPL source = getDragSource();
+
+     logCompIndex("importData from", source);
+     logCompIndex("importData to", target);
+
+     
+     int toIdx  = getDropRow(target, info.getDropLocation());
+     int maxIdx = getRowCount(target);
+     if (toIdx < 0 || toIdx > maxIdx)
+        toIdx = maxIdx;
+     target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+     try {
+      if ( target == source ) {
+         // REORDER within same list component
+         Integer fromIdx = (Integer)info.getTransferable().getTransferData(localObjectFlavor);
+         if (fromIdx != -1 && fromIdx != toIdx) {
+           reorderListItems(target, getSelectedRows(target), fromIdx, toIdx);
+           return true;
+         }
+       } else {
+         // MOVE from list component to another list
+         Integer fromIdx = (Integer)info.getTransferable().getTransferData(localObjectFlavor);
+         if ( fromIdx != -1 ) {
+           moveListItems(source,getSelectedRows(source), fromIdx, target, toIdx);
+           return true;
+         }
+       }
+     } catch (Exception e) {
+        e.printStackTrace();
+     }
+     return false;
+  }
+  
+  /**
+   * Returns whether drag and drop within the same list component is allowed (to
+   * reorder the elements).
+   */
+  public boolean isInnerListDragAllowed() {
+    return this.innerListDragAllowed;
+  }
+  
+  /**
+   * Returns the source list component, the drag is performed on.
+   * @return {@code null} if no drag and drop action is in progress
+   */
+  public LIST_IMPL getDragSource() {
+    return this.dragSourceComp;
+  }
+
+  /**
+   * Returns the target list component, the drop is performed on.
+   * @return {@code null} if no drag and drop action is in progress
+   */
+  public LIST_IMPL getDropTarget() {
+    return this.dropTargetComp;
+  }
+
+  
+  /**
+   * Resets cursors and initializes {@link #dropTargetComp} and {@link #dragSourceComp}.
+   */
+  @Override
+  protected void exportDone(JComponent c, Transferable t, int act) {
+    logCompIndex("exportDone", c);
+    // reset cursors
+    c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+    if ( dropTargetComp != null )
+      dropTargetComp.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+    // initialize source and target components 
+    this.dragSourceComp = null;
+    this.dropTargetComp = null;
+  }
+  
+  /**
+   * Returns the number of rows for a list component.
+   */
+  protected abstract int getRowCount(LIST_IMPL listComp);
+
+  /**
+   * Returns the selected rows for a list component.
+   */
+  protected abstract int[] getSelectedRows(LIST_IMPL listComp);
+
+  /**
+   * Returns the selected row for a list component.
+   */
+  protected abstract int getSelectedRow(LIST_IMPL listComp);
+  
+  /**
+   * Converts a drop location in a row number for a list component.
+   */
+  protected abstract int getDropRow(LIST_IMPL listComp, DropLocation dl);
+  
+  /**
+   * Reorders the rows in a list component. This must be implemented individually
+   * for the underlying list or table model. 
+   * @param listComp list component to reorder the elements in
+   * @param selIdx   selected row numbers (in table coordinates!)
+   * @param fromIdx  row number (in table coordinates!) the element(s) are moved
+   *                 from
+   * @param toIdx    row number (in table coordinates!) the element(s) should be
+   *                 moved to
+   */
+  protected abstract void reorderListItems(LIST_IMPL listComp, int[] selIdx, int from, int toIdx);
+
+  /**
+   * Reorders the rows in a list component. This must be implemented individually
+   * for the underlying list or table model. 
+   * @param fromList source list component to the selected elements come from
+   * @param selIdx   selected row numbers in {@code fromList} (in table coordinates!)
+   * @param fromIdx  row number in {@code fromList} (in table coordinates!) the element(s)
+   *                 are moved from
+   * @param toList   target list component the selected elements must be inserted in
+   * @param toIdx    row number in {@code toList} (in table coordinates!) the element(s)
+   *                 should be moved to
+   */
+  protected abstract void moveListItems(LIST_IMPL fromList, int[] selIdx, int from, LIST_IMPL toList, int toIdx);
+
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code setTransferHandler(TransferHandler)}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   * @param transferHandler {@link TransferHandler} to be set (normally {@code this})
+   */
+  public abstract void setTransferHandler(LIST_IMPL listComp, TransferHandler transferHandler);
+  
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code getTransferHandler()}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   */
+  public abstract TransferHandler getTransferHandler(LIST_IMPL listComp);
+
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code setDropMode(DropMode)}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   * @param dropMode {@link DropMode} to be set
+   */
+  public abstract void setDropMode(LIST_IMPL listComp, DropMode dropMode);
+  
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code getDropMode()}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   */
+  public abstract DropMode getDropMode(LIST_IMPL listComp);
+  
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code setDragEnabled(boolean)}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   * @param enabled  indicates whether drag is enabled
+   */
+  public abstract void setDragEnabled(LIST_IMPL listComp, boolean enabled);
+  
+  /**
+   * Because there is no common interface for drag & drop and e.g. 
+   * {@link JList} and {@link JTable} each implement {@code getDragEnabled()}
+   * for their own, we let the subclass implement it (which has knowledge about
+   * {@link LIST_IMPL}). 
+   * @param listComp list component
+   */
+  public abstract boolean getDragEnabled(LIST_IMPL listComp);
+}



More information about the Schmitzm-commits mailing list