Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java
41159 views
1
/*
2
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.awt.datatransfer;
27
28
import java.io.IOException;
29
import java.util.Arrays;
30
import java.util.HashSet;
31
import java.util.Objects;
32
import java.util.Set;
33
34
import sun.datatransfer.DataFlavorUtil;
35
36
/**
37
* A class that implements a mechanism to transfer data using cut/copy/paste
38
* operations.
39
* <p>
40
* {@link FlavorListener}s may be registered on an instance of the Clipboard
41
* class to be notified about changes to the set of {@link DataFlavor}s
42
* available on this clipboard (see {@link #addFlavorListener}).
43
*
44
* @author Amy Fowler
45
* @author Alexander Gerasimov
46
* @see java.awt.Toolkit#getSystemClipboard
47
* @see java.awt.Toolkit#getSystemSelection
48
* @since 1.1
49
*/
50
public class Clipboard {
51
52
String name;
53
54
/**
55
* The owner of the clipboard.
56
*/
57
protected ClipboardOwner owner;
58
59
/**
60
* Contents of the clipboard.
61
*/
62
protected Transferable contents;
63
64
/**
65
* An aggregate of flavor listeners registered on this local clipboard.
66
*
67
* @since 1.5
68
*/
69
private Set<FlavorListener> flavorListeners;
70
71
/**
72
* A set of {@code DataFlavor}s that is available on this local clipboard.
73
* It is used for tracking changes of {@code DataFlavor}s available on this
74
* clipboard.
75
*
76
* @since 1.5
77
*/
78
private Set<DataFlavor> currentDataFlavors;
79
80
/**
81
* Creates a clipboard object.
82
*
83
* @param name for the clipboard
84
* @see java.awt.Toolkit#getSystemClipboard
85
*/
86
public Clipboard(String name) {
87
this.name = name;
88
}
89
90
/**
91
* Returns the name of this clipboard object.
92
*
93
* @return the name of this clipboard object
94
* @see java.awt.Toolkit#getSystemClipboard
95
*/
96
public String getName() {
97
return name;
98
}
99
100
/**
101
* Sets the current contents of the clipboard to the specified transferable
102
* object and registers the specified clipboard owner as the owner of the
103
* new contents.
104
* <p>
105
* If there is an existing owner different from the argument {@code owner},
106
* that owner is notified that it no longer holds ownership of the clipboard
107
* contents via an invocation of {@code ClipboardOwner.lostOwnership()} on
108
* that owner. An implementation of {@code setContents()} is free not to
109
* invoke {@code lostOwnership()} directly from this method. For example,
110
* {@code lostOwnership()} may be invoked later on a different thread. The
111
* same applies to {@code FlavorListener}s registered on this clipboard.
112
* <p>
113
* The method throws {@code IllegalStateException} if the clipboard is
114
* currently unavailable. For example, on some platforms, the system
115
* clipboard is unavailable while it is accessed by another application.
116
*
117
* @param contents the transferable object representing the clipboard
118
* content
119
* @param owner the object which owns the clipboard content
120
* @throws IllegalStateException if the clipboard is currently unavailable
121
* @see java.awt.Toolkit#getSystemClipboard
122
*/
123
public synchronized void setContents(Transferable contents, ClipboardOwner owner) {
124
final ClipboardOwner oldOwner = this.owner;
125
final Transferable oldContents = this.contents;
126
127
this.owner = owner;
128
this.contents = contents;
129
130
if (oldOwner != null && oldOwner != owner) {
131
DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
132
oldOwner.lostOwnership(Clipboard.this, oldContents));
133
}
134
fireFlavorsChanged();
135
}
136
137
/**
138
* Returns a transferable object representing the current contents of the
139
* clipboard. If the clipboard currently has no contents, it returns
140
* {@code null}. The parameter Object requestor is not currently used. The
141
* method throws {@code IllegalStateException} if the clipboard is currently
142
* unavailable. For example, on some platforms, the system clipboard is
143
* unavailable while it is accessed by another application.
144
*
145
* @param requestor the object requesting the clip data (not used)
146
* @return the current transferable object on the clipboard
147
* @throws IllegalStateException if the clipboard is currently unavailable
148
* @see java.awt.Toolkit#getSystemClipboard
149
*/
150
public synchronized Transferable getContents(Object requestor) {
151
return contents;
152
}
153
154
/**
155
* Returns an array of {@code DataFlavor}s in which the current contents of
156
* this clipboard can be provided. If there are no {@code DataFlavor}s
157
* available, this method returns a zero-length array.
158
*
159
* @return an array of {@code DataFlavor}s in which the current contents of
160
* this clipboard can be provided
161
* @throws IllegalStateException if this clipboard is currently unavailable
162
* @since 1.5
163
*/
164
public DataFlavor[] getAvailableDataFlavors() {
165
Transferable cntnts = getContents(null);
166
if (cntnts == null) {
167
return new DataFlavor[0];
168
}
169
return cntnts.getTransferDataFlavors();
170
}
171
172
/**
173
* Returns whether or not the current contents of this clipboard can be
174
* provided in the specified {@code DataFlavor}.
175
*
176
* @param flavor the requested {@code DataFlavor} for the contents
177
* @return {@code true} if the current contents of this clipboard can be
178
* provided in the specified {@code DataFlavor}; {@code false}
179
* otherwise
180
* @throws NullPointerException if {@code flavor} is {@code null}
181
* @throws IllegalStateException if this clipboard is currently unavailable
182
* @since 1.5
183
*/
184
public boolean isDataFlavorAvailable(DataFlavor flavor) {
185
if (flavor == null) {
186
throw new NullPointerException("flavor");
187
}
188
189
Transferable cntnts = getContents(null);
190
if (cntnts == null) {
191
return false;
192
}
193
return cntnts.isDataFlavorSupported(flavor);
194
}
195
196
/**
197
* Returns an object representing the current contents of this clipboard in
198
* the specified {@code DataFlavor}. The class of the object returned is
199
* defined by the representation class of {@code flavor}.
200
*
201
* @param flavor the requested {@code DataFlavor} for the contents
202
* @return an object representing the current contents of this clipboard in
203
* the specified {@code DataFlavor}
204
* @throws NullPointerException if {@code flavor} is {@code null}
205
* @throws IllegalStateException if this clipboard is currently unavailable
206
* @throws UnsupportedFlavorException if the requested {@code DataFlavor} is
207
* not available
208
* @throws IOException if the data in the requested {@code DataFlavor} can
209
* not be retrieved
210
* @see DataFlavor#getRepresentationClass
211
* @since 1.5
212
*/
213
public Object getData(DataFlavor flavor)
214
throws UnsupportedFlavorException, IOException {
215
if (flavor == null) {
216
throw new NullPointerException("flavor");
217
}
218
219
Transferable cntnts = getContents(null);
220
if (cntnts == null) {
221
throw new UnsupportedFlavorException(flavor);
222
}
223
return cntnts.getTransferData(flavor);
224
}
225
226
/**
227
* Registers the specified {@code FlavorListener} to receive
228
* {@code FlavorEvent}s from this clipboard. If {@code listener} is
229
* {@code null}, no exception is thrown and no action is performed.
230
*
231
* @param listener the listener to be added
232
* @see #removeFlavorListener
233
* @see #getFlavorListeners
234
* @see FlavorListener
235
* @see FlavorEvent
236
* @since 1.5
237
*/
238
public synchronized void addFlavorListener(FlavorListener listener) {
239
if (listener == null) {
240
return;
241
}
242
243
if (flavorListeners == null) {
244
flavorListeners = new HashSet<>();
245
currentDataFlavors = getAvailableDataFlavorSet();
246
}
247
248
flavorListeners.add(listener);
249
}
250
251
/**
252
* Removes the specified {@code FlavorListener} so that it no longer
253
* receives {@code FlavorEvent}s from this {@code Clipboard}. This method
254
* performs no function, nor does it throw an exception, if the listener
255
* specified by the argument was not previously added to this
256
* {@code Clipboard}. If {@code listener} is {@code null}, no exception is
257
* thrown and no action is performed.
258
*
259
* @param listener the listener to be removed
260
* @see #addFlavorListener
261
* @see #getFlavorListeners
262
* @see FlavorListener
263
* @see FlavorEvent
264
* @since 1.5
265
*/
266
public synchronized void removeFlavorListener(FlavorListener listener) {
267
if (listener == null || flavorListeners == null) {
268
return;
269
}
270
flavorListeners.remove(listener);
271
}
272
273
/**
274
* Returns an array of all the {@code FlavorListener}s currently registered
275
* on this {@code Clipboard}.
276
*
277
* @return all of this clipboard's {@code FlavorListener}s or an empty array
278
* if no listeners are currently registered
279
* @see #addFlavorListener
280
* @see #removeFlavorListener
281
* @see FlavorListener
282
* @see FlavorEvent
283
* @since 1.5
284
*/
285
public synchronized FlavorListener[] getFlavorListeners() {
286
return flavorListeners == null ? new FlavorListener[0] :
287
flavorListeners.toArray(new FlavorListener[flavorListeners.size()]);
288
}
289
290
/**
291
* Checks change of the {@code DataFlavor}s and, if necessary, notifies all
292
* listeners that have registered interest for notification on
293
* {@code FlavorEvent}s.
294
*
295
* @since 1.5
296
*/
297
private void fireFlavorsChanged() {
298
if (flavorListeners == null) {
299
return;
300
}
301
302
Set<DataFlavor> prevDataFlavors = currentDataFlavors;
303
currentDataFlavors = getAvailableDataFlavorSet();
304
if (Objects.equals(prevDataFlavors, currentDataFlavors)) {
305
return;
306
}
307
flavorListeners.forEach(listener ->
308
DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
309
listener.flavorsChanged(new FlavorEvent(Clipboard.this))));
310
}
311
312
/**
313
* Returns a set of {@code DataFlavor}s currently available on this
314
* clipboard.
315
*
316
* @return a set of {@code DataFlavor}s currently available on this
317
* clipboard
318
* @since 1.5
319
*/
320
private Set<DataFlavor> getAvailableDataFlavorSet() {
321
Set<DataFlavor> set = new HashSet<>();
322
Transferable contents = getContents(null);
323
if (contents != null) {
324
DataFlavor[] flavors = contents.getTransferDataFlavors();
325
if (flavors != null) {
326
set.addAll(Arrays.asList(flavors));
327
}
328
}
329
return set;
330
}
331
}
332
333