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

天涯浪子 提交于 2019-12-08 02:51:38

问题


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

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