001/* 002 * $Source: v:/cvsroot/open/projects/WebARTS/ca/bc/webarts/widgets/dnd/TransferableObject.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/** 030 * At last an easy way to encapsulate your custom objects for dragging and dropping 031 * in your Java programs! 032 * When you need to create a {@link java.awt.datatransfer.Transferable} object, 033 * use this class to wrap your object. 034 * For example: 035 * <pre><code> 036 * ... 037 * MyCoolClass myObj = new MyCoolClass(); 038 * Transferable xfer = new TransferableObject( myObj ); 039 * ... 040 * </code></pre> 041 * Or if you need to know when the data was actually dropped, like when you're 042 * moving data out of a list, say, you can use the {@link TransferableObject.Fetcher} 043 * inner class to return your object Just in Time. 044 * For example: 045 * <pre><code> 046 * ... 047 * final MyCoolClass myObj = new MyCoolClass(); 048 * 049 * TransferableObject.Fetcher fetcher = new TransferableObject.Fetcher() 050 * { public Object getObject(){ return myObj; } 051 * }; // end fetcher 052 * 053 * Transferable xfer = new TransferableObject( fetcher ); 054 * ... 055 * </code></pre> 056 * 057 * The {@link java.awt.datatransfer.DataFlavor} associated with 058 * {@link TransferableObject} has the representation class 059 * <tt>net.iharder.dnd.TransferableObject.class</tt> and MIME type 060 * <tt>application/x-net.iharder.dnd.TransferableObject</tt>. 061 * This data flavor is accessible via the static 062 * {@link #DATA_FLAVOR} property. 063 * 064 * 065 * <p><em>This code is licensed for public use under the Common Public License version 0.5.</em><br/> 066 * The Common Public License, developed by IBM and modeled after their industry-friendly IBM Public License, 067 * differs from other common open source licenses in several important ways: 068 * <ul> 069 * <li>You may include this software with other software that uses a different (even non-open source) license.</li> 070 * <li>You may use this software to make for-profit software.</li> 071 * <li>Your patent rights, should you generate patents, are protected.</li> 072 * </ul> 073 * </p> 074 * <p><em>Copyright ? 2001 Robert Harder</em></p> 075 * 076 * @author Robert.Harder 077 * @copyright 2001 078 * @version 1.1 079 */ 080public class TransferableObject implements java.awt.datatransfer.Transferable 081{ 082 /** 083 * The MIME type for {@link #DATA_FLAVOR} is 084 * <tt>application/x-net.iharder.dnd.TransferableObject</tt>. 085 * 086 * @since 1.1 087 */ 088 public final static String MIME_TYPE = "application/x-net.iharder.dnd.TransferableObject"; 089 090 091 /** 092 * The default {@link java.awt.datatransfer.DataFlavor} for 093 * {@link TransferableObject} has the representation class 094 * <tt>net.iharder.dnd.TransferableObject.class</tt> 095 * and the MIME type 096 * <tt>application/x-net.iharder.dnd.TransferableObject</tt>. 097 * 098 * @since 1.1 099 */ 100 public final static java.awt.datatransfer.DataFlavor DATA_FLAVOR = 101 new java.awt.datatransfer.DataFlavor( ca.bc.webarts.widgets.dnd.TransferableObject.class, MIME_TYPE ); 102 103 104 private Fetcher fetcher; 105 private Object data; 106 107 private java.awt.datatransfer.DataFlavor customFlavor; 108 109 110 111 /** 112 * Creates a new {@link TransferableObject} that wraps <var>data</var>. 113 * Along with the {@link #DATA_FLAVOR} associated with this class, 114 * this creates a custom data flavor with a representation class 115 * determined from <code>data.getClass()</code> and the MIME type 116 * <tt>application/x-net.iharder.dnd.TransferableObject</tt>. 117 * 118 * @param data The data to transfer 119 * @since 1.1 120 */ 121 public TransferableObject( Object data ) 122 { this.data = data; 123 this.customFlavor = new java.awt.datatransfer.DataFlavor( data.getClass(), MIME_TYPE ); 124 } // end constructor 125 126 127 128 /** 129 * Creates a new {@link TransferableObject} that will return the 130 * object that is returned by <var>fetcher</var>. 131 * No custom data flavor is set other than the default 132 * {@link #DATA_FLAVOR}. 133 * 134 * @see Fetcher 135 * @param fetcher The {@link Fetcher} that will return the data object 136 * @since 1.1 137 */ 138 public TransferableObject( Fetcher fetcher ) 139 { this.fetcher = fetcher; 140 } // end constructor 141 142 143 144 /** 145 * Creates a new {@link TransferableObject} that will return the 146 * object that is returned by <var>fetcher</var>. 147 * Along with the {@link #DATA_FLAVOR} associated with this class, 148 * this creates a custom data flavor with a representation class <var>dataClass</var> 149 * and the MIME type 150 * <tt>application/x-net.iharder.dnd.TransferableObject</tt>. 151 * 152 * @see Fetcher 153 * @param dataClass The {@link java.lang.Class} to use in the custom data flavor 154 * @param fetcher The {@link Fetcher} that will return the data object 155 * @since 1.1 156 */ 157 public TransferableObject( Class dataClass, Fetcher fetcher ) 158 { this.fetcher = fetcher; 159 this.customFlavor = new java.awt.datatransfer.DataFlavor( dataClass, MIME_TYPE ); 160 } // end constructor 161 162 /** 163 * Returns the custom {@link java.awt.datatransfer.DataFlavor} associated 164 * with the encapsulated object or <tt>null</tt> if the {@link Fetcher} 165 * constructor was used without passing a {@link java.lang.Class}. 166 * 167 * @return The custom data flavor for the encapsulated object 168 * @since 1.1 169 */ 170 public java.awt.datatransfer.DataFlavor getCustomDataFlavor() 171 { return customFlavor; 172 } // end getCustomDataFlavor 173 174 175/* ******** T R A N S F E R A B L E M E T H O D S ******** */ 176 177 178 /** 179 * Returns a two- or three-element array containing first 180 * the custom data flavor, if one was created in the constructors, 181 * second the default {@link #DATA_FLAVOR} associated with 182 * {@link TransferableObject}, and third the 183 * {@link java.awt.datatransfer.DataFlavor.stringFlavor}. 184 * 185 * @return An array of supported data flavors 186 * @since 1.1 187 */ 188 public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() 189 { 190 if( customFlavor != null ) 191 return new java.awt.datatransfer.DataFlavor[] 192 { customFlavor, 193 DATA_FLAVOR, 194 java.awt.datatransfer.DataFlavor.stringFlavor 195 }; // end flavors array 196 else 197 return new java.awt.datatransfer.DataFlavor[] 198 { DATA_FLAVOR, 199 java.awt.datatransfer.DataFlavor.stringFlavor 200 }; // end flavors array 201 } // end getTransferDataFlavors 202 203 204 205 /** 206 * Returns the data encapsulated in this {@link TransferableObject}. 207 * If the {@link Fetcher} constructor was used, then this is when 208 * the {@link Fetcher#getObject getObject()} method will be called. 209 * If the requested data flavor is not supported, then the 210 * {@link Fetcher#getObject getObject()} method will not be called. 211 * 212 * @param flavor The data flavor for the data to return 213 * @return The dropped data 214 * @since 1.1 215 */ 216 public Object getTransferData( java.awt.datatransfer.DataFlavor flavor ) 217 throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException 218 { 219 // Native object 220 if( flavor.equals( DATA_FLAVOR ) ) 221 return fetcher == null ? data : fetcher.getObject(); 222 223 // String 224 if( flavor.equals( java.awt.datatransfer.DataFlavor.stringFlavor ) ) 225 return fetcher == null ? data.toString() : fetcher.getObject().toString(); 226 227 // We can't do anything else 228 throw new java.awt.datatransfer.UnsupportedFlavorException(flavor); 229 } // end getTransferData 230 231 232 233 234 /** 235 * Returns <tt>true</tt> if <var>flavor</var> is one of the supported 236 * flavors. Flavors are supported using the <code>equals(...)</code> method. 237 * 238 * @param flavor The data flavor to check 239 * @return Whether or not the flavor is supported 240 * @since 1.1 241 */ 242 public boolean isDataFlavorSupported( java.awt.datatransfer.DataFlavor flavor ) 243 { 244 // Native object 245 if( flavor.equals( DATA_FLAVOR ) ) 246 return true; 247 248 // String 249 if( flavor.equals( java.awt.datatransfer.DataFlavor.stringFlavor ) ) 250 return true; 251 252 // We can't do anything else 253 return false; 254 } // end isDataFlavorSupported 255 256 257/* ******** I N N E R I N T E R F A C E F E T C H E R ******** */ 258 259 /** 260 * Instead of passing your data directly to the {@link TransferableObject} 261 * constructor, you may want to know exactly when your data was received 262 * in case you need to remove it from its source (or do anyting else to it). 263 * When the {@link #getTransferData getTransferData(...)} method is called 264 * on the {@link TransferableObject}, the {@link Fetcher}'s 265 * {@link #getObject getObject()} method will be called. 266 * 267 * @author Robert Harder 268 * @copyright 2001 269 * @version 1.1 270 * @since 1.1 271 */ 272 public static interface Fetcher 273 { 274 /** 275 * Return the object being encapsulated in the 276 * {@link TransferableObject}. 277 * 278 * @return The dropped object 279 * @since 1.1 280 */ 281 public abstract Object getObject(); 282 } // end inner interface Fetcher 283 284 285 286} // end class TransferableObject 287