我正在开发包含JFreeChart的Eclipse RCP应用程序。 其function之一是将graphics复制到剪贴板以便将其粘贴到其他应用程序中,但在Linux上不起作用,
有一个SWT示例 ,你可以find一个在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 64bit上都失败了。 有没有办法来实现它?
提前致谢!
编辑:
将JFreeChartgraphics复制到文件但不复制到剪贴板中的代码
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); }
试试这个代码:
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});
将图像复制到剪贴板不适用于Linux 64上的SWT,自2009年以来,Eclipse跟踪器上存在一个问题 。
我做了一个解决方案SWT传输实施,将图像复制为PNG。
它适用于Ubuntu 64,未在其他平台上测试过。
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; } }