2

我正在开发一个包含 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);
                    }
4

2 回答 2

2

将图像复制到剪贴板不适用于 Linux 64 上的 SWT,自 2009 年以来 Eclipse 跟踪器上存在一个问题。

我做了一个解决方法 SWT Transfer 实现,将图像复制为 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;
    }

}
于 2017-08-22T13:45:13.003 回答
0

试试这个代码:

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});
于 2012-10-03T11:28:37.800 回答