001 /* Clipboard.java -- Class for transferring data via cut and paste. 002 Copyright (C) 1999, 2001, 2005, 2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package java.awt.datatransfer; 040 041 import java.io.IOException; 042 import java.util.ArrayList; 043 044 /** 045 * This class allows data to be transferred using a cut and paste type 046 * mechanism. 047 * 048 * @author Aaron M. Renn (arenn@urbanophile.com) 049 * @author Mark J. Wielaard (mark@klomp.org) 050 */ 051 public class Clipboard 052 { 053 /** 054 * The data currently on this clipboard. For use by 055 * subclasses. Also returned by the public method getContents(). 056 */ 057 protected Transferable contents; 058 059 /** 060 * The owner of this clipboard. 061 */ 062 protected ClipboardOwner owner; 063 064 // The clipboard name 065 private final String name; 066 067 // The flavor listeners (most likely small). 068 private final ArrayList listeners = new ArrayList(3); 069 070 /** 071 * Initializes a new instance of <code>Clipboard</code> with the 072 * specified name. 073 * 074 * @param name The clipboard name. 075 */ 076 public Clipboard(String name) 077 { 078 this.name = name; 079 } 080 081 /** 082 * Returns the name of the clipboard. 083 */ 084 public String getName() 085 { 086 return name; 087 } 088 089 /** 090 * Returns the contents of the clipboard. 091 * 092 * @param requestor The object requesting the contents. This 093 * implementation ignores this parameter. 094 * 095 * @exception IllegalStateException If the clipboard is currently unavailable 096 */ 097 public synchronized Transferable getContents(Object requestor) 098 { 099 return contents; 100 } 101 102 /** 103 * Sets the content and owner of this clipboard. If the given owner 104 * is different from the current owner then <code>lostOwnership()</code> 105 * is called on the current owner with the old contents of the given 106 * clipboard. 107 * 108 * @param contents The new clipboard contents. 109 * @param owner The new clipboard owner 110 * 111 * @exception IllegalStateException If the clipboard is currently unavailable 112 */ 113 public synchronized void setContents(Transferable contents, 114 ClipboardOwner owner) 115 { 116 Transferable oldContents = getContents(null); 117 this.contents = contents; 118 if (this.owner != owner) 119 { 120 ClipboardOwner oldOwner = this.owner; 121 this.owner = owner; 122 if (oldOwner != null) 123 oldOwner.lostOwnership(this, oldContents); 124 } 125 126 FlavorListener[] fs = getFlavorListeners(); 127 if (fs.length > 0) 128 { 129 // We are a bit optimistic here. We assume DataFlavors will be 130 // given in the same order. If the number of flavors is 131 // different or the order of the DataFlavors in the list then 132 // fire a change event. 133 boolean newFlavors = ((contents != null && oldContents == null) 134 || (contents == null && oldContents != null)); 135 if (!newFlavors && contents != null && oldContents != null) 136 { 137 DataFlavor[] df1 = contents.getTransferDataFlavors(); 138 DataFlavor[] df2 = oldContents.getTransferDataFlavors(); 139 newFlavors = df1.length != df2.length; 140 141 for (int i = 0; !newFlavors && i < df1.length; i++) 142 newFlavors = !df1[i].equals(df2[i]); 143 } 144 145 if (newFlavors) 146 { 147 FlavorEvent e = new FlavorEvent(this); 148 for (int i = 0; i < fs.length; i++) 149 fs[i].flavorsChanged(e); 150 } 151 } 152 } 153 154 public DataFlavor[] getAvailableDataFlavors() 155 { 156 Transferable c = getContents(null); 157 if (c == null) 158 return new DataFlavor[0]; 159 else 160 return c.getTransferDataFlavors(); 161 } 162 163 public boolean isDataFlavorAvailable(DataFlavor flavor) 164 { 165 DataFlavor[] fs = getAvailableDataFlavors(); 166 for (int i = 0; i < fs.length; i++) 167 if (flavor.equals(fs[i])) 168 return true; 169 170 return false; 171 } 172 173 public Object getData(DataFlavor flavor) 174 throws UnsupportedFlavorException, IOException 175 { 176 Transferable c = getContents(null); 177 if (c == null) 178 throw new UnsupportedFlavorException(flavor); 179 else 180 return c.getTransferData(flavor); 181 } 182 183 public void addFlavorListener(FlavorListener listener) 184 { 185 if (listener == null) 186 return; 187 188 synchronized(listeners) 189 { 190 listeners.add(listener); 191 } 192 } 193 194 public void removeFlavorListener(FlavorListener listener) 195 { 196 if (listener == null) 197 return; 198 199 synchronized(listeners) 200 { 201 listeners.remove(listener); 202 } 203 } 204 205 public FlavorListener[] getFlavorListeners() 206 { 207 synchronized(listeners) 208 { 209 return (FlavorListener[]) 210 listeners.toArray(new FlavorListener[listeners.size()]); 211 } 212 } 213 }