复制到全局剪贴板不适用于 Ubuntu 中的 Java

2022-09-01 14:25:50

来自独立应用程序的以下代码适用于 ubuntu:

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

public class ClipboardTest {

    public static void main(String[] args) throws Exception {
        Clipboard clipBoard = Toolkit.getDefaultToolkit().getSystemClipboard();        
        // print the last copied thing
        System.out.println(clipBoard.getContents(null).getTransferData(DataFlavor.stringFlavor));
        StringSelection data = new StringSelection("NOW");
        clipBoard.setContents(data, data);
        // prints NOW
        System.out.println(clipBoard.getContents(null).getTransferData(DataFlavor.stringFlavor));
    }

}

将(Ctrl+V)粘贴到其他应用程序中不会产生任何结果;我期待“现在”。再次调用上述代码会给出以下异常:

Exception in thread "main" java.awt.datatransfer.UnsupportedFlavorException: Unicode String
    at sun.awt.datatransfer.ClipboardTransferable.getTransferData(ClipboardTransferable.java:160)

作为一个独立的应用程序,即使在 2011 年安全更改之后,这也应该有效。通过Ctrl+C从JTextField内部复制,然后粘贴到其他地方是有效的。

在ubuntu 11.04上使用最新的java7(jdk1.7.0_10)和jdk1.6.0_33都失败了;它应该在Windows 7和具有最新java7的Windows 7和具有java6_37的mac osx 10.6上工作并且确实可以正常工作。还尝试了 xubuntu 12.04 与这些 java,它在那里不起作用。这是一个 linux/ubuntu 错误吗?

相关问题


答案 1

我在工作中遇到了同样的应用程序问题,这是我找到的一篇文章,解释了原因和可能的解决方案。我希望它有帮助。

为什么会发生这种情况

剪贴板持久性是一个错误,它会影响 Ubuntu 和其他基于 X11 的操作系统下的许多程序。修复它是Google Summer of Code 2010项目。维基百科对这个问题有很好的概述。如果要以用户身份进行修复,可以安装 Parcellite 或其他剪贴板管理器。如果要以程序员的身份修复它,可以修改程序以符合剪贴板管理器规范。

X-窗口维基

使用 gnome 库,您可以在剪贴板上调用存储方法并修复此问题。这是迄今为止唯一值得尝试的事情。在GTK上也看到了类似的东西,但只是在Eclipse的错误中。


答案 2

我用 debian 测试 (7.0) 和 openjdk 7u3 尝试了你的代码。结果是一样的,但我认为我发现了问题(解决方案)。

剪贴板中的内容仅在进程存在时才有效。如果我把你的代码改成这个,它的工作原理:

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;

public class ClipboardTest {

    public static void main(String[] args) throws Exception {
        Clipboard clipBoard = Toolkit.getDefaultToolkit().getSystemClipboard();
        // print the last copied thing
        Transferable t = clipBoard.getContents(null);
        if (t.isDataFlavorSupported(DataFlavor.stringFlavor))
            System.out.println(t.getTransferData(DataFlavor.stringFlavor));
        StringSelection data = new StringSelection("NOW");
        clipBoard.setContents(data, data);
        // prints NOW
        System.out.println(clipBoard.getContents(null).getTransferData(DataFlavor.stringFlavor));
        System.in.read();
    }
}

if 语句可防止代码在没有可用内容时引发异常,如果运行代码一次并且进程结束,就会发生这种情况。
System.in.read() 只是使进程保持活动状态。虽然没有按回车键,但我可以粘贴到另一个应用程序中,“NOW”按预期出现。
像这样,代码每次都适用于我。

希望这有帮助。