KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > datatransfer > Clipboard


1 /*
2  * @(#)Clipboard.java 1.22 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.datatransfer;
9
10 import java.awt.EventQueue JavaDoc;
11
12 import java.util.Set JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.Arrays JavaDoc;
15
16 import java.io.IOException JavaDoc;
17
18 import sun.awt.EventListenerAggregate;
19
20
21 /**
22  * A class that implements a mechanism to transfer data using
23  * cut/copy/paste operations.
24  * <p>
25  * {@link FlavorListener}s may be registered on an instance of the
26  * Clipboard class to be notified about changes to the set of
27  * {@link DataFlavor}s available on this clipboard (see
28  * {@link #addFlavorListener}).
29  *
30  * @see java.awt.Toolkit#getSystemClipboard
31  * @see java.awt.Toolkit#getSystemSelection
32  *
33  * @version 1.22, 12/19/03
34  * @author Amy Fowler
35  * @author Alexander Gerasimov
36  */

37 public class Clipboard {
38
39     String JavaDoc name;
40
41     protected ClipboardOwner JavaDoc owner;
42     protected Transferable JavaDoc contents;
43
44     /**
45      * An aggregate of flavor listeners registered on this local clipboard.
46      *
47      * @since 1.5
48      */

49     private EventListenerAggregate flavorListeners;
50
51     /**
52      * A set of <code>DataFlavor</code>s that is available on
53      * this local clipboard. It is used for tracking changes
54      * of <code>DataFlavor/code>s available on this clipboard.
55      *
56      * @since 1.5
57      */

58     private Set JavaDoc currentDataFlavors;
59
60     /**
61      * Creates a clipboard object.
62      *
63      * @see java.awt.Toolkit#getSystemClipboard
64      */

65     public Clipboard(String JavaDoc name) {
66         this.name = name;
67     }
68
69     /**
70      * Returns the name of this clipboard object.
71      *
72      * @see java.awt.Toolkit#getSystemClipboard
73      */

74     public String JavaDoc getName() {
75         return name;
76     }
77
78     /**
79      * Sets the current contents of the clipboard to the specified
80      * transferable object and registers the specified clipboard owner
81      * as the owner of the new contents.
82      * <p>
83      * If there is an existing owner different from the argument
84      * <code>owner</code>, that owner is notified that it no longer
85      * holds ownership of the clipboard contents via an invocation
86      * of <code>ClipboardOwner.lostOwnership()</code> on that owner.
87      * An implementation of <code>setContents()</code> is free not
88      * to invoke <code>lostOwnership()</code> directly from this method.
89      * For example, <code>lostOwnership()</code> may be invoked later on
90      * a different thread. The same applies to <code>FlavorListener</code>s
91      * registered on this clipboard.
92      * <p>
93      * The method throws <code>IllegalStateException</code> if the clipboard
94      * is currently unavailable. For example, on some platforms, the system
95      * clipboard is unavailable while it is accessed by another application.
96      *
97      * @param contents the transferable object representing the
98      * clipboard content
99      * @param owner the object which owns the clipboard content
100      * @throws IllegalStateException if the clipboard is currently unavailable
101      * @see java.awt.Toolkit#getSystemClipboard
102      */

103     public synchronized void setContents(Transferable JavaDoc contents, ClipboardOwner JavaDoc owner) {
104         final ClipboardOwner JavaDoc oldOwner = this.owner;
105         final Transferable JavaDoc oldContents = this.contents;
106   
107         this.owner = owner;
108         this.contents = contents;
109
110         if (oldOwner != null && oldOwner != owner) {
111             EventQueue.invokeLater(new Runnable JavaDoc() {
112                 public void run() {
113                     oldOwner.lostOwnership(Clipboard.this, oldContents);
114                 }
115             });
116         }
117         fireFlavorsChanged();
118     }
119
120     /**
121      * Returns a transferable object representing the current contents
122      * of the clipboard. If the clipboard currently has no contents,
123      * it returns <code>null</code>. The parameter Object requestor is
124      * not currently used. The method throws
125      * <code>IllegalStateException</code> if the clipboard is currently
126      * unavailable. For example, on some platforms, the system clipboard is
127      * unavailable while it is accessed by another application.
128      *
129      * @param requestor the object requesting the clip data (not used)
130      * @return the current transferable object on the clipboard
131      * @throws IllegalStateException if the clipboard is currently unavailable
132      * @see java.awt.Toolkit#getSystemClipboard
133      */

134     public synchronized Transferable JavaDoc getContents(Object JavaDoc requestor) {
135         return contents;
136     }
137
138
139     /**
140      * Returns an array of <code>DataFlavor</code>s in which the current
141      * contents of this clipboard can be provided. If there are no
142      * <code>DataFlavor</code>s available, this method returns a zero-length
143      * array.
144      *
145      * @return an array of <code>DataFlavor</code>s in which the current
146      * contents of this clipboard can be provided
147      *
148      * @throws IllegalStateException if this clipboard is currently unavailable
149      *
150      * @since 1.5
151      */

152     public DataFlavor JavaDoc[] getAvailableDataFlavors() {
153         Transferable JavaDoc cntnts = getContents(null);
154         if (cntnts == null) {
155             return new DataFlavor JavaDoc[0];
156         }
157         return cntnts.getTransferDataFlavors();
158     }
159
160     /**
161      * Returns whether or not the current contents of this clipboard can be
162      * provided in the specified <code>DataFlavor</code>.
163      *
164      * @param flavor the requested <code>DataFlavor</code> for the contents
165      *
166      * @return <code>true</code> if the current contents of this clipboard
167      * can be provided in the specified <code>DataFlavor</code>;
168      * <code>false</code> otherwise
169      *
170      * @throws NullPointerException if <code>flavor</code> is <code>null</code>
171      * @throws IllegalStateException if this clipboard is currently unavailable
172      *
173      * @since 1.5
174      */

175     public boolean isDataFlavorAvailable(DataFlavor JavaDoc flavor) {
176         if (flavor == null) {
177             throw new NullPointerException JavaDoc("flavor");
178         }
179
180         Transferable JavaDoc cntnts = getContents(null);
181         if (cntnts == null) {
182             return false;
183         }
184         return cntnts.isDataFlavorSupported(flavor);
185     }
186
187     /**
188      * Returns an object representing the current contents of this clipboard
189      * in the specified <code>DataFlavor</code>.
190      * The class of the object returned is defined by the representation
191      * class of <code>flavor</code>.
192      *
193      * @param flavor the requested <code>DataFlavor</code> for the contents
194      *
195      * @return an object representing the current contents of this clipboard
196      * in the specified <code>DataFlavor</code>
197      *
198      * @throws NullPointerException if <code>flavor</code> is <code>null</code>
199      * @throws IllegalStateException if this clipboard is currently unavailable
200      * @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
201      * is not available
202      * @throws IOException if the data in the requested <code>DataFlavor</code>
203      * can not be retrieved
204      *
205      * @see DataFlavor#getRepresentationClass
206      *
207      * @since 1.5
208      */

209     public Object JavaDoc getData(DataFlavor JavaDoc flavor)
210         throws UnsupportedFlavorException JavaDoc, IOException JavaDoc {
211         if (flavor == null) {
212             throw new NullPointerException JavaDoc("flavor");
213         }
214
215         Transferable JavaDoc cntnts = getContents(null);
216         if (cntnts == null) {
217             throw new UnsupportedFlavorException JavaDoc(flavor);
218         }
219         return cntnts.getTransferData(flavor);
220     }
221
222
223     /**
224      * Registers the specified <code>FlavorListener</code> to receive
225      * <code>FlavorEvent</code>s from this clipboard.
226      * If <code>listener</code> is <code>null</code>, no exception
227      * is thrown and no action is performed.
228      *
229      * @param listener the listener to be added
230      *
231      * @see #removeFlavorListener
232      * @see #getFlavorListeners
233      * @see FlavorListener
234      * @see FlavorEvent
235      * @since 1.5
236      */

237     public synchronized void addFlavorListener(FlavorListener JavaDoc listener) {
238         if (listener == null) {
239             return;
240         }
241         if (flavorListeners == null) {
242             currentDataFlavors = getAvailableDataFlavorSet();
243             flavorListeners = new EventListenerAggregate(FlavorListener JavaDoc.class);
244         }
245         flavorListeners.add(listener);
246     }
247
248     /**
249      * Removes the specified <code>FlavorListener</code> so that it no longer
250      * receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
251      * This method performs no function, nor does it throw an exception, if
252      * the listener specified by the argument was not previously added to this
253      * <code>Clipboard</code>.
254      * If <code>listener</code> is <code>null</code>, no exception
255      * is thrown and no action is performed.
256      *
257      * @param listener the listener to be removed
258      *
259      * @see #addFlavorListener
260      * @see #getFlavorListeners
261      * @see FlavorListener
262      * @see FlavorEvent
263      * @since 1.5
264      */

265     public synchronized void removeFlavorListener(FlavorListener JavaDoc listener) {
266         if (listener == null || flavorListeners == null) {
267             return;
268         }
269         flavorListeners.remove(listener);
270     }
271
272     /**
273      * Returns an array of all the <code>FlavorListener</code>s currently
274      * registered on this <code>Clipboard</code>.
275      *
276      * @return all of this clipboard's <code>FlavorListener</code>s or an empty
277      * array if no listeners are currently registered
278      * @see #addFlavorListener
279      * @see #removeFlavorListener
280      * @see FlavorListener
281      * @see FlavorEvent
282      * @since 1.5
283      */

284     public synchronized FlavorListener JavaDoc[] getFlavorListeners() {
285         return flavorListeners == null ? new FlavorListener JavaDoc[0] :
286                 (FlavorListener JavaDoc[])flavorListeners.getListenersCopy();
287     }
288
289     /**
290      * Checks change of the <code>DataFlavor</code>s and, if necessary,
291      * notifies all listeners that have registered interest for notification
292      * on <code>FlavorEvent</code>s.
293      *
294      * @since 1.5
295      */

296     private void fireFlavorsChanged() {
297         if (flavorListeners == null) {
298             return;
299         }
300         Set JavaDoc prevDataFlavors = currentDataFlavors;
301         currentDataFlavors = getAvailableDataFlavorSet();
302         if (prevDataFlavors.equals(currentDataFlavors)) {
303             return;
304         }
305         FlavorListener JavaDoc[] flavorListenerArray =
306                 (FlavorListener JavaDoc[])flavorListeners.getListenersInternal();
307         for (int i = 0; i < flavorListenerArray.length; i++) {
308             final FlavorListener JavaDoc listener = flavorListenerArray[i];
309             EventQueue.invokeLater(new Runnable JavaDoc() {
310                 public void run() {
311                     listener.flavorsChanged(new FlavorEvent JavaDoc(Clipboard.this));
312                 }
313             });
314         }
315     }
316
317     /**
318      * Returns a set of <code>DataFlavor</code>s currently available
319      * on this clipboard.
320      *
321      * @return a set of <code>DataFlavor</code>s currently available
322      * on this clipboard
323      *
324      * @since 1.5
325      */

326     private Set JavaDoc getAvailableDataFlavorSet() {
327         Set JavaDoc set = new HashSet JavaDoc();
328         Transferable JavaDoc contents = getContents(null);
329         if (contents != null) {
330             DataFlavor JavaDoc[] flavors = contents.getTransferDataFlavors();
331             if (flavors != null) {
332                 set.addAll(Arrays.asList(flavors));
333             }
334         }
335         return set;
336     }
337 }
338
339     
340
341     
342
Popular Tags