28

以下来自独立应用程序的代码在 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 内部复制,然后粘贴到其他地方。

使用最新的 java7 (jdk1.7.0_10) 和 jdk1.6.0_33 在 ubuntu 11.04 上均未成功;它应该可以在带有最新 java7 的 windows 7 和带有 java6_37 的 mac osx 10.6 上按预期工作。还用这些java尝试了xubuntu 12.04,但它在那里不起作用。这是一个 linux/ubuntu 错误吗?

相关问题

4

4 回答 4

19

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

为什么会发生

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

X-Window 维基

使用 gnome 库,您可以调用剪贴板上的 store 方法并修复此问题。到目前为止,这似乎是唯一值得尝试的事情。也看到了 GTK 的类似情况,但仅在 Eclipse 的错误中。

于 2013-01-22T20:59:50.430 回答
14

我用 debian testing (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() 只是保持进程活着。虽然不按回车键,但我可以粘贴到另一个应用程序中,“现在”按预期出现。
像这样,代码每次都对我有用。

希望这可以帮助。

于 2013-01-21T21:44:42.903 回答
4

问:你有没有尝试过这样的事情:

gksudo gedit /opt/java/64/jre1.7.0_04/lib/security/java.policy=>

permission java.awt.AWTPermission "accessClipboard";

也可以看看:

于 2013-01-19T22:38:37.563 回答
1

在这里你可以展示一个测试:

一个 TextArea(它的默认复制/粘贴操作可以与 ubuntu 上的任何其他应用程序一起使用)

我添加了两个按钮,可以从/向系统剪贴板复制和粘贴

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.io.IOException;

public class PruebaClipboard {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Copy/Paste");
        frame.getContentPane().setLayout(new BorderLayout());
        JPanel btnPanel = new JPanel();
        JButton btnCopy = new JButton("copy");
        JButton btnPaste = new JButton("paste");
        btnPanel.add(btnCopy);
        btnPanel.add(btnPaste);
        final JTextArea textComp = new JTextArea(7,15);

        Action copyAction = new AbstractAction("copy") {
            public void actionPerformed(ActionEvent e) {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                StringSelection stringSelection = new StringSelection(textComp.getText());
                clipboard.setContents(stringSelection, stringSelection);
            }
        };

        btnCopy.setAction(copyAction);
        Action pasteAction = new AbstractAction("paste") {
            public void actionPerformed(ActionEvent e) {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                //odd: the Object param of getContents is not currently used
                Transferable contents = clipboard.getContents(null);
                boolean hasTransferableText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor);
                if (hasTransferableText) {
                    try {
                        String result = "";
                        result = (String) contents.getTransferData(DataFlavor.stringFlavor);
                        textComp.append(result);
                    } catch (UnsupportedFlavorException ex) {
                        //highly unlikely since we are using a standard DataFlavor
                        System.out.println(ex);
                        ex.printStackTrace();
                    } catch (IOException ex) {
                        System.out.println(ex);
                        ex.printStackTrace();
                    }
                }
            }
        };
        btnPaste.setAction(pasteAction);

        frame.getContentPane().add(textComp);
        frame.getContentPane().add(btnPanel, BorderLayout.SOUTH);

        frame.setSize(new Dimension(400, 300));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

我认为您必须注意:

boolean hasTransferableText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor);

并看到有一个DataFlavor.plainTextFlavor这可能是您需要使用的(尽管它已被弃用)

我已经在 Ubuntu 12.10 上测试了从 java 1.4 到 java 1.6 的代码,但是我提取它的代码自我记得 ubuntu 9.0 以来一直在使用。

于 2013-01-25T14:33:46.773 回答