Java 使用默认编辑器工具包将文本放入系统剪贴板

Java 使用默认编辑器工具包将文本放入系统剪贴板,java,swing,clipboard,Java,Swing,Clipboard,一个月以来,我一直在尝试在我的程序中可靠地设置系统剪贴板。目前它的工作效率约为95/100倍。但我一直在寻找 昨天我偶然发现了这一点,看到已经写了一些东西,可以做我想做的事,我就死了 虽然问题是这是一个对话框的“动作” 我如何发布要复制到剪贴板的文本?我不希望将此“操作”附加到我应用程序中的任何按钮/组件。我希望能够做到 DefaultEditorKit.copyAction("Put this on Clipboard"); 但这是未定义的。我不知道如何触发这个“动作”,并给它一些文本来处理

一个月以来,我一直在尝试在我的程序中可靠地设置系统剪贴板。目前它的工作效率约为95/100倍。但我一直在寻找

昨天我偶然发现了这一点,看到已经写了一些东西,可以做我想做的事,我就死了

虽然问题是这是一个对话框的“动作”

我如何发布要复制到剪贴板的文本?我不希望将此“操作”附加到我应用程序中的任何按钮/组件。我希望能够做到

DefaultEditorKit.copyAction("Put this on Clipboard");
但这是未定义的。我不知道如何触发这个“动作”,并给它一些文本来处理

编辑:这是导致异常的代码

public void setClip2(String arg)
{
    while(true) 
    {
        try
        {
            sysClip.setContents(new StringSelection(arg), null);
        }
        catch(Exception e)
        {
            try {Thread.sleep(20);} catch (InterruptedException e1) {}
            continue;
        }
        break;
    }
    return;
}

DefaultEditorKit.copyAction
实际使用(通过某些层)java.awt.datatransfer中的函数性。在那里,您可以找到将数据发送到剪贴板的类

基本上,如果您只想在不使用任何Swing组件的情况下将字符串发送到剪贴板,您可以设置一个
ClipboardOwner
,创建一个
StringSelection
对象,然后将其交给系统剪贴板。下面是一个最基本的例子:

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents( new StringSelection("Put this on Clipboard"), new ClipboardOwner() {

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
      System.out.println("I am no longer the clipboard owner.");
    }
} );
我只是想知道是否有一种方法可以可靠地设置剪贴板。(如果您没有等待足够长的时间尝试设置,此方法将失败,通常为1-2秒

不确定为什么要等待设置剪贴板的内容

此程序每200ms刷新一次剪贴板没有任何问题。也就是说,每次按预期显示时,该数字都会增加1:

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;

class ClipboardLoopTest
{
    public static void main(String[] args)
        throws InterruptedException
    {
        for (int i = 0; i < 100; i++)
        {
            //  add data to clipboard

            try
            {
                Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
                StringSelection testData;
                testData = new StringSelection( "Test: " + i );
                c.setContents(testData, testData);

                //  Get clipboard contents, as a String

                Transferable t = c.getContents( null );

                if ( t.isDataFlavorSupported(DataFlavor.stringFlavor) )
                {
                    Object o = t.getTransferData( DataFlavor.stringFlavor );
                    String data = (String)t.getTransferData( DataFlavor.stringFlavor );
                    System.out.println( "Clipboard contents: " + data );
                }
            }
            catch(Exception e)
            {
                System.out.println(e);
            }

            Thread.sleep(200);
        }

        System.exit(0);
    }
}
import java.awt.*;
导入java.awt.datatransfer.*;
导入java.io.*;
类剪贴簿循环测试
{
公共静态void main(字符串[]args)
抛出中断异常
{
对于(int i=0;i<100;i++)
{
//将数据添加到剪贴板
尝试
{
剪贴板c=Toolkit.getDefaultToolkit().getSystemClipboard();
字符串选择测试数据;
testData=新的字符串选择(“测试:+i”);
c、 setContents(testData,testData);
//以字符串形式获取剪贴板内容
可转移t=c.getContents(null);
如果(支持t.IsDataFlavor(DataFlavor.stringFlavor))
{
对象o=t.getTransferData(DataFlavor.stringFlavor);
字符串数据=(字符串)t.getTransferData(DataFlavor.stringFlavor);
System.out.println(“剪贴板内容:+数据”);
}
}
捕获(例外e)
{
系统输出打印ln(e);
}
睡眠(200);
}
系统出口(0);
}
}
我在Windows7上使用JDK7


也许你可以发布你的SSCCE来演示这个问题。

你目前是如何设置的?(95/100次有效的方法)我使用剪贴板。设置内容(“测试”)方法(在西里尔的回答中概述)。但对于此方法,我必须等待setContents没有引发异常。我通过进入while循环,然后继续,直到没有遇到异常;通常为1-2秒。但是如果我没有等待足够长的时间(有时长达4秒),我无法在尝试使用我认为已设置的文本之前设置剪贴板。(我将调用while循环,等待4秒钟,然后尝试使用剪贴板上的文本,而剪贴板有时不在那里)@BumSkeeter,发布的代码如何可编译?你在哪里调用代码?你如何让你的代码实际生成异常。正如我在发布代码时告诉你的,我给你的代码从未生成异常,因此你的循环代码似乎不必要。除非你能告诉我们你如何生成执行选项,否则我们无法分析问题em.这就是我一直在做的。有时剪贴板.setContents()无法设置内容。(您必须将setContents放入一个try catch中)我只是在while循环中进行设置,因此如果遇到异常,它会重试,直到没有遇到异常。我只是想知道是否有方法可以可靠地设置剪贴板。(如果您没有等待足够长的时间尝试设置它,此方法将失败,通常约为1-2秒,但有时它第一次尝试就可以工作,并且需要<1秒。文档说
如果剪贴板当前不可用,此方法将抛出IllegalStateException。例如,在某些平台上,当用户访问系统剪贴板时,系统剪贴板不可用。)另一个应用程序。
这就是发生在你身上的事情吗?无论如何,看看
DefaultEditorKit.copyAction()
的源代码,它没有做任何比这更有趣的事情。是的,这就是发生在我身上的事情。所以copyAction做的事情与我基本上做的事情完全相同。只要等到没有引发异常为止?(它如何知道等待多长时间?;在成功设置剪贴板之前是否会返回?)我怎样才能看到源代码?对不起,我没有说清楚:默认编辑器工具包的复制操作在工作之前不会循环。我想,它只会尝试一次,如果失败,就会提供错误反馈。如果你得到Oracle的JDK,你会在文件
src.zip
中找到源代码。这仍然可能无法将剪贴板设置为所需的文本。我f setContents()抛出异常,则不会为该i设置剪贴板。我等待设置它的意思是,我进入无限循环,而(true),如果抛出异常,我将执行“继续”,否则我将执行“中断”。这保证最终我会将剪贴板设置为所需的文本。我将尝试最终删除该文本,并使其成为单行调用。例如,setClip(text)这不会引发异常。我通过在窗口中运行上述代码并同时运行记事本来测试代码。在记事本中,我一直按住CTRL-C键将记事本文本复制到剪贴板,而我的程序一直在运行。我从来都无法生成异常。因此,发布您的SSCCE,它实际上会生成