136dad7197
Reviewed-by: serb
292 lines
9.2 KiB
Java
292 lines
9.2 KiB
Java
/*
|
|
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
import java.awt.Image;
|
|
import java.awt.Toolkit;
|
|
import java.awt.datatransfer.Clipboard;
|
|
import java.awt.datatransfer.ClipboardOwner;
|
|
import java.awt.datatransfer.DataFlavor;
|
|
import java.awt.datatransfer.FlavorEvent;
|
|
import java.awt.datatransfer.FlavorListener;
|
|
import java.awt.datatransfer.Transferable;
|
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
|
|
|
public class Common {}
|
|
|
|
class FlavorListenerImpl implements FlavorListener {
|
|
public boolean notified1, notified2;
|
|
private int count;
|
|
public void flavorsChanged(FlavorEvent evt) {
|
|
switch (count) {
|
|
case 0:
|
|
notified1 = true;
|
|
break;
|
|
case 1:
|
|
notified2 = true;
|
|
break;
|
|
}
|
|
count++;
|
|
System.err.println("listener's " + this +
|
|
" flavorChanged() called " + count + " time");
|
|
}
|
|
public String toString() {
|
|
return "notified1=" + notified1 + " notified2=" + notified2 +
|
|
" count=" + count;
|
|
}
|
|
};
|
|
|
|
class Util {
|
|
public static void setClipboardContents(Clipboard cb,
|
|
Transferable contents,
|
|
ClipboardOwner owner) {
|
|
while (true) {
|
|
try {
|
|
cb.setContents(contents, owner);
|
|
return;
|
|
} catch (IllegalStateException ise) {
|
|
ise.printStackTrace();
|
|
try {
|
|
Thread.sleep(100);
|
|
} catch (InterruptedException ie) {
|
|
ie.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void sleep(long millis) {
|
|
try {
|
|
Thread.sleep(millis);
|
|
} catch (InterruptedException ie) {
|
|
ie.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public static Image createImage() {
|
|
int w = 100;
|
|
int h = 100;
|
|
int[] pix = new int[w * h];
|
|
|
|
int index = 0;
|
|
for (int y = 0; y < h; y++) {
|
|
for (int x = 0; x < w; x++) {
|
|
int red = 127;
|
|
int green = 127;
|
|
int blue = y > h / 2 ? 127 : 0;
|
|
int alpha = 255;
|
|
if (x < w / 4 && y < h / 4) {
|
|
alpha = 0;
|
|
red = 0;
|
|
}
|
|
pix[index++] = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
}
|
|
}
|
|
|
|
return Toolkit
|
|
.getDefaultToolkit().
|
|
createImage(new java.awt.image.MemoryImageSource(
|
|
w, h, pix, 0, w
|
|
));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
class TransferableUnion implements Transferable {
|
|
|
|
private static final DataFlavor[] ZERO_LENGTH_ARRAY = new DataFlavor[0];
|
|
|
|
private final Transferable TRANSF1, TRANSF2;
|
|
|
|
private final DataFlavor[] FLAVORS;
|
|
|
|
|
|
public TransferableUnion(Transferable t1, Transferable t2) {
|
|
if (t1 == null) {
|
|
throw new NullPointerException("t1");
|
|
}
|
|
if (t2 == null) {
|
|
throw new NullPointerException("t2");
|
|
}
|
|
|
|
this.TRANSF1 = t1;
|
|
this.TRANSF2 = t2;
|
|
|
|
java.util.Set<DataFlavor> flavorSet = new java.util.HashSet<>();
|
|
flavorSet.addAll(java.util.Arrays.asList(t1.getTransferDataFlavors()));
|
|
flavorSet.addAll(java.util.Arrays.asList(t2.getTransferDataFlavors()));
|
|
|
|
FLAVORS = flavorSet.toArray(ZERO_LENGTH_ARRAY);
|
|
}
|
|
|
|
/**
|
|
* Returns an array of flavors in which this <code>Transferable</code>
|
|
* can provide the data.
|
|
*/
|
|
public DataFlavor[] getTransferDataFlavors() {
|
|
return FLAVORS.clone();
|
|
}
|
|
|
|
/**
|
|
* Returns whether the requested flavor is supported by this
|
|
* <code>Transferable</code>.
|
|
*
|
|
* @param flavor the requested flavor for the data
|
|
* @throws NullPointerException if flavor is <code>null</code>
|
|
*/
|
|
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
|
if (flavor == null) {
|
|
throw new NullPointerException("flavor");
|
|
}
|
|
|
|
return TRANSF1.isDataFlavorSupported(flavor)
|
|
|| TRANSF2.isDataFlavorSupported(flavor);
|
|
}
|
|
|
|
/**
|
|
* Returns the <code>Transferable</code>'s data in the requested
|
|
* <code>DataFlavor</code> if possible.
|
|
*
|
|
* @param flavor the requested flavor for the data
|
|
* @return the data in the requested flavor
|
|
* @throws UnsupportedFlavorException if the requested data flavor is
|
|
* not supported by this Transferable
|
|
* @throws IOException if an <code>IOException</code> occurs while
|
|
* retrieving the data.
|
|
* @throws NullPointerException if flavor is <code>null</code>
|
|
*/
|
|
public Object getTransferData(DataFlavor flavor)
|
|
throws UnsupportedFlavorException, java.io.IOException {
|
|
|
|
if (!isDataFlavorSupported(flavor)) {
|
|
throw new UnsupportedFlavorException(flavor);
|
|
}
|
|
|
|
java.io.IOException ioexc = null;
|
|
|
|
if (TRANSF1.isDataFlavorSupported(flavor)) {
|
|
try {
|
|
return TRANSF1.getTransferData(flavor);
|
|
} catch (java.io.IOException exc) {
|
|
ioexc = exc;
|
|
}
|
|
}
|
|
|
|
if (TRANSF2.isDataFlavorSupported(flavor)) {
|
|
return TRANSF2.getTransferData(flavor);
|
|
}
|
|
|
|
if (ioexc != null) {
|
|
throw ioexc;
|
|
}
|
|
|
|
// unreachable
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* A <code>Transferable</code> that implements the capability required
|
|
* to transfer an <code>Image</code>.
|
|
*
|
|
* This <code>Transferable</code> properly supports
|
|
* <code>DataFlavor.imageFlavor</code>
|
|
* and all equivalent flavors.
|
|
* No other <code>DataFlavor</code>s are supported.
|
|
*
|
|
* @see java.awt.datatransfer.DataFlavor.imageFlavor
|
|
*/
|
|
class ImageSelection implements Transferable {
|
|
|
|
private static final DataFlavor[] flavors = { DataFlavor.imageFlavor };
|
|
|
|
private Image data;
|
|
|
|
/**
|
|
* Creates a <code>Transferable</code> capable of transferring
|
|
* the specified <code>Image</code>.
|
|
*/
|
|
public ImageSelection(Image data) {
|
|
this.data = data;
|
|
}
|
|
|
|
/**
|
|
* Returns an array of flavors in which this <code>Transferable</code>
|
|
* can provide the data. <code>DataFlavor.stringFlavor</code>
|
|
* is supported.
|
|
*
|
|
* @return an array of length one, whose element is <code>DataFlavor.
|
|
* imageFlavor</code>
|
|
*/
|
|
public DataFlavor[] getTransferDataFlavors() {
|
|
return flavors.clone();
|
|
}
|
|
|
|
/**
|
|
* Returns whether the requested flavor is supported by this
|
|
* <code>Transferable</code>.
|
|
*
|
|
* @param flavor the requested flavor for the data
|
|
* @return true if <code>flavor</code> is equal to
|
|
* <code>DataFlavor.imageFlavor</code>;
|
|
* false otherwise
|
|
* @throws NullPointerException if flavor is <code>null</code>
|
|
*/
|
|
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
|
for (int i = 0; i < flavors.length; i++) {
|
|
if (flavor.equals(flavors[i])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns the <code>Transferable</code>'s data in the requested
|
|
* <code>DataFlavor</code> if possible. If the desired flavor is
|
|
* <code>DataFlavor.imageFlavor</code>, or an equivalent flavor,
|
|
* the <code>Image</code> representing the selection is
|
|
* returned.
|
|
*
|
|
* @param flavor the requested flavor for the data
|
|
* @return the data in the requested flavor, as outlined above
|
|
* @throws UnsupportedFlavorException if the requested data flavor is
|
|
* not equivalent to <code>DataFlavor.imageFlavor</code>
|
|
* @throws IOException if an <code>IOException</code> occurs while
|
|
* retrieving the data. By default, <code>ImageSelection</code>
|
|
* never throws this exception, but a subclass may.
|
|
* @throws NullPointerException if flavor is <code>null</code>
|
|
*/
|
|
public Object getTransferData(DataFlavor flavor)
|
|
throws UnsupportedFlavorException, java.io.IOException {
|
|
if (flavor.equals(DataFlavor.imageFlavor)) {
|
|
return data;
|
|
} else {
|
|
throw new UnsupportedFlavorException(flavor);
|
|
}
|
|
}
|
|
|
|
} // class ImageSelection
|
|
|