/* * 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 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 Transferable * can provide the data. */ public DataFlavor[] getTransferDataFlavors() { return FLAVORS.clone(); } /** * Returns whether the requested flavor is supported by this * Transferable. * * @param flavor the requested flavor for the data * @throws NullPointerException if flavor is null */ public boolean isDataFlavorSupported(DataFlavor flavor) { if (flavor == null) { throw new NullPointerException("flavor"); } return TRANSF1.isDataFlavorSupported(flavor) || TRANSF2.isDataFlavorSupported(flavor); } /** * Returns the Transferable's data in the requested * DataFlavor 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 IOException occurs while * retrieving the data. * @throws NullPointerException if flavor is null */ 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 Transferable that implements the capability required * to transfer an Image. * * This Transferable properly supports * DataFlavor.imageFlavor * and all equivalent flavors. * No other DataFlavors are supported. * * @see java.awt.datatransfer.DataFlavor.imageFlavor */ class ImageSelection implements Transferable { private static final DataFlavor[] flavors = { DataFlavor.imageFlavor }; private Image data; /** * Creates a Transferable capable of transferring * the specified Image. */ public ImageSelection(Image data) { this.data = data; } /** * Returns an array of flavors in which this Transferable * can provide the data. DataFlavor.stringFlavor * is supported. * * @return an array of length one, whose element is DataFlavor. * imageFlavor */ public DataFlavor[] getTransferDataFlavors() { return flavors.clone(); } /** * Returns whether the requested flavor is supported by this * Transferable. * * @param flavor the requested flavor for the data * @return true if flavor is equal to * DataFlavor.imageFlavor; * false otherwise * @throws NullPointerException if flavor is null */ public boolean isDataFlavorSupported(DataFlavor flavor) { for (int i = 0; i < flavors.length; i++) { if (flavor.equals(flavors[i])) { return true; } } return false; } /** * Returns the Transferable's data in the requested * DataFlavor if possible. If the desired flavor is * DataFlavor.imageFlavor, or an equivalent flavor, * the Image 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 DataFlavor.imageFlavor * @throws IOException if an IOException occurs while * retrieving the data. By default, ImageSelection * never throws this exception, but a subclass may. * @throws NullPointerException if flavor is null */ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, java.io.IOException { if (flavor.equals(DataFlavor.imageFlavor)) { return data; } else { throw new UnsupportedFlavorException(flavor); } } } // class ImageSelection