I'm making a program using java that sends the clipboard contents over sockets; I managed to make it work with strings but I'm having some troubles with images. Here is the code:
//get Image
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Image imageContents = (Image)clipboard.getData(DataFlavor.imageFlavor);
ImageIcon image = new ImageIcon(imageContents);
//sent over sockets
//set Image
String mime = DataFlavor.imageFlavor.getMimeType();
DataHandler contents = new DataHandler(image,mime);
//set clipboard
clipboard.setContents(contents, null);
After setContents the clipboard is empty; Any ideas why, and how to fix it?
Here is some code I've used to write/read an Image from the clipboard. Never tried it with sockets so I'm not sure it will help:
import java.awt.*;
import java.awt.datatransfer.*;
public class ClipboardImage
{
/**
* Retrieve an image from the system clipboard.
*
* @return the image from the clipboard or null if no image is found
*/
public static Image read()
{
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents( null );
try
{
if (t != null && t.isDataFlavorSupported(DataFlavor.imageFlavor))
{
Image image = (Image)t.getTransferData(DataFlavor.imageFlavor);
return image;
}
}
catch (Exception e) {}
return null;
}
/**
* Place an image on the system clipboard.
*
* @param image - the image to be added to the system clipboard
*/
public static void write(Image image)
{
if (image == null)
throw new IllegalArgumentException ("Image can't be null");
ImageTransferable transferable = new ImageTransferable( image );
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(transferable, null);
}
static class ImageTransferable implements Transferable
{
private Image image;
public ImageTransferable (Image image)
{
this.image = image;
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException
{
if (isDataFlavorSupported(flavor))
{
return image;
}
else
{
throw new UnsupportedFlavorException(flavor);
}
}
public boolean isDataFlavorSupported (DataFlavor flavor)
{
return flavor == DataFlavor.imageFlavor;
}
public DataFlavor[] getTransferDataFlavors ()
{
return new DataFlavor[] { DataFlavor.imageFlavor };
}
}
public static void main(String[] args)
{
Image image = Toolkit.getDefaultToolkit ().createImage("???.jpg");
ClipboardImage.write( image );
javax.swing.ImageIcon icon = new javax.swing.ImageIcon( ClipboardImage.read() );
javax.swing.JLabel label = new javax.swing.JLabel( icon );
javax.swing.JFrame frame = new javax.swing.JFrame();
frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( label );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
DataHandler will not function in the way you've prescribed because according to the API:
DataHandler implements the Transferable interface so that data can be used in AWT data transfer operations, such as cut and paste and drag and drop. The implementation of the Transferable interface relies on the availability of an installed DataContentHandler object corresponding to the MIME type of the data represented in the specific instance of the DataHandler.
I understand this to mean that unless you use its setDataContentHandlerFactory
method and implement all required interfaces therein, essentially, DataHandler will simply return null. This is likely the reason why DataHandler does not function as you expect. Even though it implements the Transferable
interface, it does not implement it in a way that functions adequately for your particular needs.
This functionality would be given by a DataContentHandler
whose implementation would be left up to you.
It seems less tedious to directly implement the Transferable class as suggested prior.