问题
I am developing an Eclipse RCP Application which includes JFreeChart. One of its features is to copy graphs to the clipboard in order to paste them into other applications but it does not work on Linux,
There is a SWT sample where you can find a snippet that does not work in Linux.
On the other hand JFreeChart implemented this on AWT as:
Clipboard systemClipboard
= Toolkit.getDefaultToolkit().getSystemClipboard();
Insets insets = getInsets();
int w = getWidth() - insets.left - insets.right;
int h = getHeight() - insets.top - insets.bottom;
ChartTransferable selection = new ChartTransferable(this.chart, w, h,
getMinimumDrawWidth(), getMinimumDrawHeight(),
getMaximumDrawWidth(), getMaximumDrawHeight(), true);
systemClipboard.setContents(selection, null);
Howewer both examples fail on Linux 64bit. Is there a way to implement it??
Thanks in advance!
EDIT:
Code that copy the JFreeChart graphic into a file but not into the Clipboard
final org.eclipse.swt.dnd.Clipboard clipboard = new org.eclipse.swt.dnd.Clipboard(menu.getDisplay());
Insets insets = source.getInsets();
int w = source.getWidth() - insets.left - insets.right;
int h = source.getHeight() - insets.top - insets.bottom;
ChartTransferable selection = new ChartTransferable(source
.getChart(), w, h, source.getMinimumDrawWidth(), source.getMinimumDrawHeight(), source
.getMaximumDrawWidth(), source.getMaximumDrawHeight(), true);
Image image = new Image(menu.getDisplay(),ImageUtils.convertToSWT(selection.getBufferedImage()));
if (image != null) {
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { image.getImageData() };
imageLoader.save("/tmp/graph.jpg", SWT.IMAGE_JPEG); // fails
ImageTransfer imageTransfer = ImageTransfer.getInstance();
clipboard.setContents(new Object[]{image.getImageData()},
new Transfer[]{imageTransfer}, DND.CLIPBOARD | DND.SELECTION_CLIPBOARD);
}
回答1:
Try this code:
JFreeChart chart = YOUR_CHART_HERE;
ChartComposite chartComposite = new ChartComposite(shell, SWT.NONE, chart, true);
Image image = new Image(Display.getDefault(), chartComposite.getBounds());
GC gc = new GC(image);
chartComposite.print(gc);
gc.dispose();
ImageTransfer imageTransfer = ImageTransfer.getInstance();
clipboard.setContents(new Object[] {image.getImageData()}, new Transfer[]{imageTransfer});
回答2:
Copying images to clipboard does not work with SWT on Linux 64, an issue exists on Eclipse tracker since 2009.
I Made a workaround SWT Transfer implementation that copies the image as PNG.
It works on Ubuntu 64, not tested on other platforms .
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
/**
* Custom clipboard transfer to work around SWT bug 283960 that make copy image to clipboard not working on Linux 64.
*
* @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=283960
*/
public class PngTransfer extends ByteArrayTransfer {
private static final String IMAGE_PNG = "image/png";
private static final int ID = registerType(IMAGE_PNG);
private static PngTransfer _instance = new PngTransfer();
private PngTransfer() {}
public static PngTransfer getInstance () {
return _instance;
}
@Override
protected String[] getTypeNames() {
return new String[]{IMAGE_PNG};
}
@Override
protected int[] getTypeIds() {
return new int[]{ID};
}
@Override
protected void javaToNative(Object object, TransferData transferData) {
if (object == null || !(object instanceof ImageData)) {
return;
}
if (isSupportedType(transferData)) {
ImageData image = (ImageData) object;
try (ByteArrayOutputStream out = new ByteArrayOutputStream();){
// write data to a byte array and then ask super to convert to pMedium
ImageLoader imgLoader = new ImageLoader();
imgLoader.data = new ImageData[] { image };
imgLoader.save(out, SWT.IMAGE_PNG);
byte[] buffer = out.toByteArray();
out.close();
super.javaToNative(buffer, transferData);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
@Override
protected Object nativeToJava(TransferData transferData) {
if (isSupportedType(transferData)) {
byte[] buffer = (byte[])super.nativeToJava(transferData);
if (buffer == null) {
return null;
}
try (ByteArrayInputStream in = new ByteArrayInputStream(buffer)){
return new ImageData(in);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return null;
}
}
来源:https://stackoverflow.com/questions/12707176/copy-image-to-clipboard-not-working-on-linux-java-awt-swt