java - 将图像复制到剪贴板在 Linux 上不起作用(Java AWT 和 SWT)

标签 java linux swt awt jfreechart

我正在开发一个 Eclipse RCP 应用程序,其中包括 JFreeChart。它的功能之一是将图形复制到剪贴板,以便将它们粘贴到其他应用程序中,但它在 Linux 上不起作用,

有一个SWT sample您可以在其中找到在 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,issue自 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;
    }

}

关于java - 将图像复制到剪贴板在 Linux 上不起作用(Java AWT 和 SWT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12707176/

相关文章:

java - 在 SWT 中设置/获取 RadioGroupFieldEditor 的值

java - 如何在 TreeViewer 中的第二列中展开列

java - 使用 POI Java 提取 Word 文档表格单元格中的内容

java - Firebase 数据库身份验证注册

linux - Perl 脚本将换行符添加到文本文件末尾

linux - 错误 : undefined reference to.。编译 GTK-3.12.2 时的长列表

php - 带有 shell_exec 的命令行 PHP 适用于 root,但不适用于其他人

Java SWT DateTime - 获取选择?

java - 如何在 SOAP 头中添加签名安全信息

java - java(Android)中通过日历函数获取负值