package com.philschatz.swt.dnd;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.internal.ole.win32.COM;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* Singleton class that reads Images (CF_DIB) from the Windows Clipboard as
* ImageData objects.
*
* If you found this class useful (or made some improvements) drop me a line.
*
*
* @author Philip Schatz ( www.philschatz.com )
*/
public class WindowsImageTransfer extends ByteArrayTransfer {
private static final WindowsImageTransfer INSTANCE = new WindowsImageTransfer();
private static final String CF_DIB = "CF_DIB";
private static final int CF_DIBID = COM.CF_DIB;
private WindowsImageTransfer() {
//Singleton
}
public static WindowsImageTransfer getInstance() {
return WindowsImageTransfer.INSTANCE;
}
protected final int[] getTypeIds() {
return new int[]{WindowsImageTransfer.CF_DIBID};
}
public final String[] getTypeNames() {
return new String[]{WindowsImageTransfer.CF_DIB};
}
protected Object nativeToJava(TransferData transferData) {
final Object o = super.nativeToJava(transferData);
final byte[] bytes = (byte[]) o;
try {
final InputStream bis = new PrependWinBMPHeaderFilterInputStream(
new UncompressDibFilterInputStream(new ByteArrayInputStream(
bytes)));
final ImageData[] data = new ImageLoader().load(bis);
if (data.length < 1) {
return null;
}
return data[0];
} catch (IOException e) {
return null;
}
}
protected void javaToNative(Object object, TransferData transferData) {
final ImageData imgData = (ImageData) object;
final ImageLoader loader = new ImageLoader();
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final byte[] bytes;
loader.data = new ImageData[]{imgData};
loader.save(new RemoveWinBMPHeaderFilterOutputStream(bos), SWT.IMAGE_BMP);
bytes = bos.toByteArray();
super.javaToNative(bytes, transferData);
}
public static void main(String[] args) throws Exception {
Display display = new Display();
Shell shell = new Shell(display);
Clipboard c = new Clipboard(display);
System.out.println("types on the clipboard: "
+ Arrays.asList(c.getAvailableTypeNames()));
Object o = c.getContents(WindowsImageTransfer.getInstance());
ImageData d = (ImageData) o;
if (d == null) {
System.out.println("no image found on clipboard. try hitting the printscreen key, or using MS Paint to put an image on the clipboard.");
return;
}
//Change what's on the clipboard to show we can also put images on the
// clipboard.
c.setContents(new Object[]{"howdy"}, new Transfer[]{TextTransfer
.getInstance()});
System.out.println("types on the clipboard: "
+ Arrays.asList(c.getAvailableTypeNames()));
//now put the ImageData back onto the clipboard.
c.setContents(new Object[]{d}, new Transfer[]{WindowsImageTransfer
.getInstance()});
System.out.println("types on the clipboard: "
+ Arrays.asList(c.getAvailableTypeNames()));
//now read the CF_DIB (ImageData) back off the clipboard.
// and display it by using it as the image for the button.
ImageData imgData = (ImageData) c.getContents(WindowsImageTransfer
.getInstance());
Image img = new Image(display, imgData);
Button button = new Button(shell, SWT.NONE);
button.setImage(img);
shell.pack();
button.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
button.dispose();
}
}