| /* | |
| * 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 | |