http://forums.sun.com/thread.jspa?threadID=576069
Hello All:
I know there has been a lot of discussion about copying images to the clipboard, and believe me, I've read them all about 20 times each. Believe it or not, I still haven't found an answer that helps. I'm hoping someone will take the time to help me out. My actual applet is more complex than the one I provide here, but I've simplified it down to make it easier to post and discuss.
I have an applet that reads in an image, stores it to a BufferedImage and an array of pixel values. Now I want to put that image on the System clipboard so that I can switch windows to PowerPoint, and paste the image in the PPT document. When I do this, I get a ClassCastException thrown at the clipboard.setContents(...) call. I can copy a string to the clipboard just fine (the code to do so is in the applet below, currently commented out), but the image always results in the ClassCastException.
One of the posts I've read indicated that if the data format doesn't match the data flavor, this exception will be thrown. I actually created an array of bytes that exactly represented a .BMP image, and set the DataFlavor to "image/bmp" but the exact same problem occurred. I could actually write the array of bytes to a file and get a BMP file that was viewable in image viewers. I'm out of things to try at this point, so any help would be very appreciated.
Some notes of interest:
I am NOT using any Swing components, and I'm hoping to keep it that way.
When I copy the string, or when I do no copying at all, the image displays perfectly, so I know it is read in correctly, and that the security policies are set to allow that.
I write and compile the code on a Sun Solaris machine, then run it via Internet Explorer and a Windows 2000 maching, running Java(TM) Plug-in: Version 1.4.2_05.
Here's the simplified applet source:
- import java.awt.*;
- import java.awt.image.*;
- import java.applet.*;
- import java.io.*;
- import java.lang.*;
- import java.util.*;
- import java.net.*;
- import java.awt.datatransfer.*; //for clipboard ops
- public class cbTest extends Applet implements ClipboardOwner
- {
- public static DataFlavor myFlavor = new DataFlavor("image/gif", "GIF Image");
- BufferedImage bufImg;
- int imgWid;
- int imgHt;
- int pix[];
- public void init()
- {
- Image img;
- URL imgURL;
- PixelGrabber pixGrab;
- imgURL = null;
- try
- {
- imgURL = new URL("file:/v://temp//java//radar.jpg");
- imgURL.openConnection().getInputStream(); //test for open...
- }
- catch (MalformedURLException e)
- {
- System.out.println("Malformed URL exception caught");
- }
- catch (Throwable t)
- {
- System.out.println("Couldn't open image");
- }
- img = getImage(imgURL);
- while (img.getWidth(this) < 0)
- {
- try
- {
- Thread.sleep(100); //could throw InterruptedException
- }
- catch (InterruptedException t)
- {
- System.out.println("Interrupted Exception Caught");
- }
- }
- imgWid = img.getWidth(this);
- imgHt = img.getHeight(this);
- pix = new int[imgWid * imgHt];
- pixGrab = new PixelGrabber(img, 0, 0, imgWid, imgHt, pix, 0, imgWid);
- try
- {
- pixGrab.grabPixels(); //could throw an InterruptedException
- }
- catch (InterruptedException e)
- {
- System.out.println("Caught interrupted exception");
- }
- bufImg = new BufferedImage(imgWid, imgHt, BufferedImage.TYPE_INT_ARGB);
- bufImg.setRGB(0, 0, imgWid, imgHt, pix, 0, imgWid);
- //copyStringToClipboard(); //This works fine!
- copyToClipboard(); //This causes a ClassCastException at the
- //clipboard.setContents(...) call.
- }
- public void paint(Graphics g)
- {
- g.drawImage(bufImg, 0, 0, this);
- }
- public void copyStringToClipboard()
- {
- Clipboard clipboard;
- StringSelection selec;
- clipboard = getToolkit().getSystemClipboard();
- selec = new StringSelection("Copy This String");
- clipboard.setContents(selec, this);
- }
- public void copyToClipboard()
- {
- Clipboard clipboard;
- MyImageSelection selec;
- clipboard = getToolkit().getSystemClipboard();
- selec = new MyImageSelection();
- clipboard.setContents(selec, this);
- }
- public void lostOwnership(Clipboard cb, Transferable trans)
- {
- System.out.println("Lost ownership of system clipboard");
- }
- public class MyImageSelection implements Transferable
- {
- public synchronized DataFlavor[] getTransferDataFlavors()
- {
- return new DataFlavor[]{myFlavor};
- }
- public boolean isDataFlavorSupported(DataFlavor flavor)
- {
- return myFlavor.equals(flavor);
- }
- public synchronized Object getTransferData(DataFlavor flavor)
- throws UnsupportedFlavorException, IOException
- {
- if (!myFlavor.equals(flavor))
- {
- throw new UnsupportedFlavorException(flavor);
- }
- return (pix);
- }
- }
- }
The ability to copy an image to the system clipboard was introducted with JDK1.4.
Image transfer didn't work with JDK1.3 and older.
You had to use JNI to build a custom dll or so to enable the transfer.
I am not aware of another way to get around using imageFlavor.
If you want to compile with JDK1.3 you can try the following.
private static DataFlavor imageFlavor;
static {
try {
java.lang.reflect.Field imageFlavorField = DataFlavor.class.getField("imageFlavor");
imageFlavor = (DataFlavor)imageFlavorField.get(null);
} catch (Exception e) { }
} // end static{}
I haven't tried it but this might work too.
new DataFlavor("image/x-java-image; class=java.awt.Image", "Image");
Look in the src.jar for the source code to DataFlavor for details.
Eugenio