我正在开发一个包含JFreeChart的Eclipse RCP应用程序。它的一个功能是将图形复制到剪贴板,以便将它们粘贴到其他应用程序中,但它在Linux、上不起作用
有一个SWT示例,您可以在其中找到一个在Linux中不起作用的片段。
另一方面,JFreeChart在AWT上实现了这一点:
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);
然而,这两个例子在Linux 64位上都失败了。有办法实现它吗??
提前感谢!
编辑:
将JFreeChart图形复制到文件中但不复制到剪贴板的代码
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);
}
将图像复制到剪贴板不适用于Linux 64上的SWT,这是自2009年以来Eclipse跟踪器上存在的一个问题。
我做了一个变通的SWT传输实现,将图像复制为PNG
它在Ubuntu64上运行,没有在其他平台上进行测试。
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;
}
}
试试这个代码:
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});