Skip to content

Commit 9b67f2f

Browse files
vieiroTheRealMDoerr
authored andcommitted
8306566: Open source several clipboard AWT tests
Backport-of: 136dad7197a1969b2b1fc325f4336c20386c5d3b
1 parent f874da3 commit 9b67f2f

File tree

6 files changed

+864
-0
lines changed

6 files changed

+864
-0
lines changed
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*
2+
* Copyright (c) 2003, 2023, 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.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.awt.Image;
25+
import java.awt.Toolkit;
26+
import java.awt.datatransfer.Clipboard;
27+
import java.awt.datatransfer.ClipboardOwner;
28+
import java.awt.datatransfer.DataFlavor;
29+
import java.awt.datatransfer.FlavorEvent;
30+
import java.awt.datatransfer.FlavorListener;
31+
import java.awt.datatransfer.Transferable;
32+
import java.awt.datatransfer.UnsupportedFlavorException;
33+
34+
public class Common {}
35+
36+
class FlavorListenerImpl implements FlavorListener {
37+
public boolean notified1, notified2;
38+
private int count;
39+
public void flavorsChanged(FlavorEvent evt) {
40+
switch (count) {
41+
case 0:
42+
notified1 = true;
43+
break;
44+
case 1:
45+
notified2 = true;
46+
break;
47+
}
48+
count++;
49+
System.err.println("listener's " + this +
50+
" flavorChanged() called " + count + " time");
51+
}
52+
public String toString() {
53+
return "notified1=" + notified1 + " notified2=" + notified2 +
54+
" count=" + count;
55+
}
56+
};
57+
58+
class Util {
59+
public static void setClipboardContents(Clipboard cb,
60+
Transferable contents,
61+
ClipboardOwner owner) {
62+
while (true) {
63+
try {
64+
cb.setContents(contents, owner);
65+
return;
66+
} catch (IllegalStateException ise) {
67+
ise.printStackTrace();
68+
try {
69+
Thread.sleep(100);
70+
} catch (InterruptedException ie) {
71+
ie.printStackTrace();
72+
}
73+
}
74+
}
75+
}
76+
77+
public static void sleep(long millis) {
78+
try {
79+
Thread.sleep(millis);
80+
} catch (InterruptedException ie) {
81+
ie.printStackTrace();
82+
}
83+
}
84+
85+
public static Image createImage() {
86+
int w = 100;
87+
int h = 100;
88+
int[] pix = new int[w * h];
89+
90+
int index = 0;
91+
for (int y = 0; y < h; y++) {
92+
for (int x = 0; x < w; x++) {
93+
int red = 127;
94+
int green = 127;
95+
int blue = y > h / 2 ? 127 : 0;
96+
int alpha = 255;
97+
if (x < w / 4 && y < h / 4) {
98+
alpha = 0;
99+
red = 0;
100+
}
101+
pix[index++] = (alpha << 24) | (red << 16) | (green << 8) | blue;
102+
}
103+
}
104+
105+
return Toolkit
106+
.getDefaultToolkit().
107+
createImage(new java.awt.image.MemoryImageSource(
108+
w, h, pix, 0, w
109+
));
110+
}
111+
112+
}
113+
114+
115+
class TransferableUnion implements Transferable {
116+
117+
private static final DataFlavor[] ZERO_LENGTH_ARRAY = new DataFlavor[0];
118+
119+
private final Transferable TRANSF1, TRANSF2;
120+
121+
private final DataFlavor[] FLAVORS;
122+
123+
124+
public TransferableUnion(Transferable t1, Transferable t2) {
125+
if (t1 == null) {
126+
throw new NullPointerException("t1");
127+
}
128+
if (t2 == null) {
129+
throw new NullPointerException("t2");
130+
}
131+
132+
this.TRANSF1 = t1;
133+
this.TRANSF2 = t2;
134+
135+
java.util.Set<DataFlavor> flavorSet = new java.util.HashSet<>();
136+
flavorSet.addAll(java.util.Arrays.asList(t1.getTransferDataFlavors()));
137+
flavorSet.addAll(java.util.Arrays.asList(t2.getTransferDataFlavors()));
138+
139+
FLAVORS = flavorSet.toArray(ZERO_LENGTH_ARRAY);
140+
}
141+
142+
/**
143+
* Returns an array of flavors in which this <code>Transferable</code>
144+
* can provide the data.
145+
*/
146+
public DataFlavor[] getTransferDataFlavors() {
147+
return FLAVORS.clone();
148+
}
149+
150+
/**
151+
* Returns whether the requested flavor is supported by this
152+
* <code>Transferable</code>.
153+
*
154+
* @param flavor the requested flavor for the data
155+
* @throws NullPointerException if flavor is <code>null</code>
156+
*/
157+
public boolean isDataFlavorSupported(DataFlavor flavor) {
158+
if (flavor == null) {
159+
throw new NullPointerException("flavor");
160+
}
161+
162+
return TRANSF1.isDataFlavorSupported(flavor)
163+
|| TRANSF2.isDataFlavorSupported(flavor);
164+
}
165+
166+
/**
167+
* Returns the <code>Transferable</code>'s data in the requested
168+
* <code>DataFlavor</code> if possible.
169+
*
170+
* @param flavor the requested flavor for the data
171+
* @return the data in the requested flavor
172+
* @throws UnsupportedFlavorException if the requested data flavor is
173+
* not supported by this Transferable
174+
* @throws IOException if an <code>IOException</code> occurs while
175+
* retrieving the data.
176+
* @throws NullPointerException if flavor is <code>null</code>
177+
*/
178+
public Object getTransferData(DataFlavor flavor)
179+
throws UnsupportedFlavorException, java.io.IOException {
180+
181+
if (!isDataFlavorSupported(flavor)) {
182+
throw new UnsupportedFlavorException(flavor);
183+
}
184+
185+
java.io.IOException ioexc = null;
186+
187+
if (TRANSF1.isDataFlavorSupported(flavor)) {
188+
try {
189+
return TRANSF1.getTransferData(flavor);
190+
} catch (java.io.IOException exc) {
191+
ioexc = exc;
192+
}
193+
}
194+
195+
if (TRANSF2.isDataFlavorSupported(flavor)) {
196+
return TRANSF2.getTransferData(flavor);
197+
}
198+
199+
if (ioexc != null) {
200+
throw ioexc;
201+
}
202+
203+
// unreachable
204+
return null;
205+
}
206+
207+
}
208+
209+
/**
210+
* A <code>Transferable</code> that implements the capability required
211+
* to transfer an <code>Image</code>.
212+
*
213+
* This <code>Transferable</code> properly supports
214+
* <code>DataFlavor.imageFlavor</code>
215+
* and all equivalent flavors.
216+
* No other <code>DataFlavor</code>s are supported.
217+
*
218+
* @see java.awt.datatransfer.DataFlavor.imageFlavor
219+
*/
220+
class ImageSelection implements Transferable {
221+
222+
private static final DataFlavor[] flavors = { DataFlavor.imageFlavor };
223+
224+
private Image data;
225+
226+
/**
227+
* Creates a <code>Transferable</code> capable of transferring
228+
* the specified <code>Image</code>.
229+
*/
230+
public ImageSelection(Image data) {
231+
this.data = data;
232+
}
233+
234+
/**
235+
* Returns an array of flavors in which this <code>Transferable</code>
236+
* can provide the data. <code>DataFlavor.stringFlavor</code>
237+
* is supported.
238+
*
239+
* @return an array of length one, whose element is <code>DataFlavor.
240+
* imageFlavor</code>
241+
*/
242+
public DataFlavor[] getTransferDataFlavors() {
243+
return flavors.clone();
244+
}
245+
246+
/**
247+
* Returns whether the requested flavor is supported by this
248+
* <code>Transferable</code>.
249+
*
250+
* @param flavor the requested flavor for the data
251+
* @return true if <code>flavor</code> is equal to
252+
* <code>DataFlavor.imageFlavor</code>;
253+
* false otherwise
254+
* @throws NullPointerException if flavor is <code>null</code>
255+
*/
256+
public boolean isDataFlavorSupported(DataFlavor flavor) {
257+
for (int i = 0; i < flavors.length; i++) {
258+
if (flavor.equals(flavors[i])) {
259+
return true;
260+
}
261+
}
262+
return false;
263+
}
264+
265+
/**
266+
* Returns the <code>Transferable</code>'s data in the requested
267+
* <code>DataFlavor</code> if possible. If the desired flavor is
268+
* <code>DataFlavor.imageFlavor</code>, or an equivalent flavor,
269+
* the <code>Image</code> representing the selection is
270+
* returned.
271+
*
272+
* @param flavor the requested flavor for the data
273+
* @return the data in the requested flavor, as outlined above
274+
* @throws UnsupportedFlavorException if the requested data flavor is
275+
* not equivalent to <code>DataFlavor.imageFlavor</code>
276+
* @throws IOException if an <code>IOException</code> occurs while
277+
* retrieving the data. By default, <code>ImageSelection</code>
278+
* never throws this exception, but a subclass may.
279+
* @throws NullPointerException if flavor is <code>null</code>
280+
*/
281+
public Object getTransferData(DataFlavor flavor)
282+
throws UnsupportedFlavorException, java.io.IOException {
283+
if (flavor.equals(DataFlavor.imageFlavor)) {
284+
return data;
285+
} else {
286+
throw new UnsupportedFlavorException(flavor);
287+
}
288+
}
289+
290+
} // class ImageSelection
291+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2003, 2023, 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.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
@test
26+
@bug 4259272
27+
@summary tests that notifications on changes to the set of DataFlavors
28+
available on a private clipboard are delivered properly
29+
@build Common
30+
@run main PrivateClipboardTest
31+
*/
32+
33+
import java.awt.datatransfer.Clipboard;
34+
import java.awt.datatransfer.StringSelection;
35+
36+
public class PrivateClipboardTest {
37+
38+
public static void main(String[] args) {
39+
new PrivateClipboardTest().start();
40+
}
41+
42+
public void start() {
43+
final Clipboard clipboard = new Clipboard("local");
44+
45+
final FlavorListenerImpl listener1 = new FlavorListenerImpl();
46+
clipboard.addFlavorListener(listener1);
47+
48+
final FlavorListenerImpl listener2 = new FlavorListenerImpl();
49+
clipboard.addFlavorListener(listener2);
50+
51+
Util.setClipboardContents(clipboard,
52+
new StringSelection("text1"), null);
53+
Util.sleep(3000);
54+
55+
clipboard.removeFlavorListener(listener1);
56+
57+
Util.setClipboardContents(clipboard,
58+
new TransferableUnion(new StringSelection("text2"),
59+
new ImageSelection(Util.createImage())), null);
60+
Util.sleep(3000);
61+
62+
System.err.println("listener1: " + listener1 + "\nlistener2: " + listener2);
63+
64+
if (!(listener1.notified1 && listener2.notified1 && !listener1.notified2
65+
&& listener2.notified2)) {
66+
throw new RuntimeException("notifications about flavor " +
67+
"changes delivered incorrectly!");
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)