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) しても何も起こりません。「今」を期待しています。上記のコードを 2 回呼び出すと、次の例外が発生します。

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

スタンドアロン アプリケーションとして、これは2011 年のセキュリティ変更の後でも機能するはずです。JTextField 内から Ctrl+C を使用してコピーし、別の場所に貼り付けると機能します。

最新の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 ウィンドウ ウィキ

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 ステートメントは、コードを 1 回実行してプロセスが終了した場合に発生する、使用可能なコンテンツがない場合にコードが例外をスローするのを防ぎます。
System.in.read() は、プロセスを維持するだけです。Enterキーを押さないで別のアプリケーションに貼り付けると、期待どおりに「NOW」が表示されます。
このように、コードは毎回機能します。

お役に立てれば。

于 2013-01-21T21:44:42.903 に答える
4

Q:次のようなことを試しましたか:

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 の他のアプリでそのまま使用できます)

システム クリップボードとの間でコピー アンド ペーストする 2 つのボタンを追加しました。

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 に答える