001/* 002 * $Source: v:/cvsroot/open/projects/WebARTS/ca/bc/webarts/widgets/dnd/DnDList.java,v $ 003 * $Name: $ 004 * $Revision: 1.1 $ 005 * $Date: 2005-04-10 11:53:16 -0700 (Sun, 10 Apr 2005) $ 006 * $Locker: $ 007 */ 008/* 009 * Copyright (C) 2001 WebARTS Design, North Vancouver Canada 010 * http://www..webarts.bc.ca 011 * 012 * This program is free software; you can redistribute it and/or modify 013 * it under the terms of the GNU General Public License as published by 014 * the Free Software Foundation; either version 2 of the License, or 015 * (at your option) any later version. 016 * 017 * This program is distributed in the hope that it will be useful, 018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 020 * GNU General Public License for more details. 021 * 022 * You should have received a copy of the GNU General Public License 023 * along with this program; if not, write to the Free Software 024 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 025 */ 026package ca.bc.webarts.widgets.dnd; 027 028/** 029 * An extension of {@link javax.swing.JList} that supports drag and drop 030 * to rearrange its contents and to move objects in and out of the list. 031 * The objects in the list will be passed either as a String by calling 032 * the object's <tt>toString()</tt> object, or if your drag and drop target 033 * accepts the {@link TransferableObject#DATA_FLAVOR} data flavor then 034 * the actual object will be passed. 035 * 036 * <p>I'm releasing this code into the Public Domain. Enjoy. 037 * </p> 038 * <p><em>Original author: Robert Harder, rharder@usa.net</em></p> 039 * 040 * @author Robert Harder 041 * @author rharder@usa.net 042 * @version 1.1 043 */ 044public class DnDList 045extends javax.swing.JList 046implements java.awt.dnd.DropTargetListener, 047 java.awt.dnd.DragSourceListener, 048 java.awt.dnd.DragGestureListener 049{ 050 051 private java.awt.dnd.DropTarget dropTarget = null; 052 053 private java.awt.dnd.DragSource dragSource = null; 054 055 private int sourceIndex = -1; 056 private int dropIndex = -1; 057 private Object sourceObject; 058 059 060 /** 061 * Constructs a default {@link DnDList} using a 062 * {@link javax.swing.DefaultListModel}. 063 * 064 * @since 1.1 065 */ 066 public DnDList() 067 { 068 super( new javax.swing.DefaultListModel() ); 069 initComponents(); 070 } // end constructor 071 072 073 074 /** 075 * Constructs a {@link DnDList} using the 076 * passed list model that must be extended from 077 * {@link javax.swing.DefaultListModel}. 078 * 079 * @param model The model to use 080 * @since 1.1 081 */ 082 public DnDList( javax.swing.DefaultListModel model ) 083 { super( model ); 084 initComponents(); 085 } // end constructor 086 087 088 089 /** 090 * Constructs a {@link DnDList} by 091 * filling in a {@link javax.swing.DefaultListModel} 092 * with the passed array of objects. 093 * 094 * @param data The data from which to construct a list 095 * @since 1.1 096 */ 097 public DnDList( Object[] data ) 098 { this(); 099 ((javax.swing.DefaultListModel)getModel()).copyInto( data ); 100 } // end constructor 101 102 103 104 105 /** 106 * Constructs a {@link DnDList} by 107 * filling in a {@link javax.swing.DefaultListModel} 108 * with the passed {@link java.util.Vector} of objects. 109 * 110 * @param data The data from which to construct a list 111 * @since 1.1 112 */ 113 public DnDList( java.util.Vector data ) 114 { this(); 115 ((javax.swing.DefaultListModel)getModel()).copyInto( data.toArray() ); 116 } // end constructor 117 118 119 120 private void initComponents() 121 { 122 dropTarget = new java.awt.dnd.DropTarget (this, this); 123 dragSource = new java.awt.dnd.DragSource(); 124 dragSource.createDefaultDragGestureRecognizer( this, java.awt.dnd.DnDConstants.ACTION_MOVE, this); 125 } // end initComponents 126 127 128/* ******** D R A G G E S T U R E L I S T E N E R M E T H O D S ******** */ 129 130 131 132 133 public void dragGestureRecognized( java.awt.dnd.DragGestureEvent event) 134 { //System.out.println( "DragGestureListener.dragGestureRecognized" ); 135 final Object selected = getSelectedValue(); 136 if ( selected != null ) 137 { 138 sourceIndex = getSelectedIndex(); 139 java.awt.datatransfer.Transferable transfer = new TransferableObject( new TransferableObject.Fetcher() 140 { /** 141 * This will be called when the transfer data is requested at the very end. 142 * At this point we can remove the object from its original place in the list. 143 */ 144 public Object getObject() 145 { 146 ((javax.swing.DefaultListModel)getModel()).remove( sourceIndex ); 147 return selected; 148 } // end getObject 149 }); // end fetcher 150 151 // as the name suggests, starts the dragging 152 dragSource.startDrag (event, java.awt.dnd.DragSource.DefaultLinkDrop, transfer, this); 153 } 154 else 155 { 156 //System.out.println( "nothing was selected"); 157 } 158 } // end dragGestureRecognized 159 160 161/* ******** D R A G S O U R C E L I S T E N E R M E T H O D S ******** */ 162 163 164 public void dragDropEnd( java.awt.dnd.DragSourceDropEvent evt ) 165 { //System.out.println( "DragSourceListener.dragDropEnd" ); 166 } // end dragDropEnd 167 168 169 public void dragEnter( java.awt.dnd.DragSourceDragEvent evt ) 170 { //System.out.println( "DragSourceListener.dragEnter" ); 171 } // end dragEnter 172 173 174 public void dragExit( java.awt.dnd.DragSourceEvent evt ) 175 { //System.out.println( "DragSourceListener.dragExit" ); 176 } // end dragExit 177 178 179 public void dragOver( java.awt.dnd.DragSourceDragEvent evt ) 180 { //System.out.println( "DragSourceListener.dragOver" ); 181 } // end dragOver 182 183 184 public void dropActionChanged( java.awt.dnd.DragSourceDragEvent evt ) 185 { //System.out.println( "DragSourceListener.dropActionChanged" ); 186 } // end dropActionChanged 187 188 189 190/* ******** D R O P T A R G E T L I S T E N E R M E T H O D S ******** */ 191 192 193 194 public void dragEnter( java.awt.dnd.DropTargetDragEvent evt ) 195 { //System.out.println( "DropTargetListener.dragEnter" ); 196 evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_MOVE); 197 } // end dragEnter 198 199 public void dragExit( java.awt.dnd.DropTargetEvent evt ) 200 { //System.out.println( "DropTargetListener.dragExit" ); 201 } // end dragExit 202 203 public void dragOver( java.awt.dnd.DropTargetDragEvent evt ) 204 { //System.out.println( "DropTargetListener.dragOver" ); 205 } // end dragOver 206 207 public void dropActionChanged( java.awt.dnd.DropTargetDragEvent evt ) 208 { //System.out.println( "DropTargetListener.dropActionChanged" ); 209 evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_MOVE); 210 } // end dropActionChanged 211 212 213 214 public void drop( java.awt.dnd.DropTargetDropEvent evt ) 215 { //System.out.println( "DropTargetListener.drop" ); 216 java.awt.datatransfer.Transferable transferable = evt.getTransferable(); 217 218 // If it's our native TransferableObject, use that 219 if( transferable.isDataFlavorSupported( TransferableObject.DATA_FLAVOR ) ) 220 { 221 evt.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE ); 222 Object obj = null; 223 try 224 { 225 obj = transferable.getTransferData( TransferableObject.DATA_FLAVOR ); 226 } // end try 227 catch( java.awt.datatransfer.UnsupportedFlavorException e ) 228 { e.printStackTrace(); 229 } // end catch 230 catch( java.io.IOException e ) 231 { e.printStackTrace(); 232 } // end catch 233 234 if( obj != null ) 235 { 236 // See where in the list we dropped the element. 237 int dropIndex = locationToIndex( evt.getLocation() ); 238 javax.swing.DefaultListModel model = (javax.swing.DefaultListModel)getModel(); 239 240 if( dropIndex < 0 ) 241 model.addElement( obj ); 242 243 // Else is it moving down the list? 244 else if( sourceIndex >= 0 && dropIndex > sourceIndex ) 245 model.add( dropIndex-1, obj ); 246 else 247 model.add( dropIndex, obj ); 248 249 } // end if: we got the object 250 251 // Else there was a problem getting the object 252 else 253 { 254 evt.rejectDrop(); 255 } // end else: can't get the object 256 } // end if: it's a native TransferableObject 257 258 // Else we can't handle this 259 else evt.rejectDrop(); 260 } // end drop 261 262 263 264} // end class DnDList 265