Copy Image to Clipboard not working on Linux (Java AWT & SWT)

巧了我就是萌 提交于 2019-12-06 06:06:31

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});

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;
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!