2012-04-06 79 views
4

我正在编写一个程序来侦听系统剪贴板中的更改。侦听器在单独的线程上运行,并在剪贴板的内容发生更改时执行一些操作(例如写入文件)。Java线程在没有专注于OSX时进入睡眠状态

我在使用ClipboardOwner interface轮询剪贴板,以便当我的程序失去剪贴板的所有权(意味着另一个进程修改了剪贴板)时,在我的程序中触发一个事件让我读取更改。

public class OwnershipClipboardListener extends Thread implements ClipboardOwner 
{ 
    private Clipboard clipB = Toolkit.getDefaultToolkit().getSystemClipboard(); 

    public void run() 
    { 
     /* Initialize ClipboardListener and gain ownership of clipboard */ 
    } 

    @Override 
    public void lostOwnership(Clipboard clipboard, Transferable transferable) 
    { 
     /* Auto-fired when I lose Clipboard ownership. 
      Can do processing and regaining ownership here */ 
    }  
} 

的问题是,在OSX上运行时,到剪贴板的任何变化被反映仅如果我手动Cmd的-Tab键以在船坞内的正在运行的进程图标。因此,如果在切换到停靠栏图标之前存在多个剪贴板操作,则只有最后一个才有效。我不在Linux或Windows上面对这个问题。

这就像线程在程序失去焦点时进入睡眠状态,但最后一个事件触发器在唤醒时仍然会触发。有什么办法可以预防这种睡眠吗?

+0

帖子[这](HTTP:// stackoverflow.com/questions/4402001/cant-copy-to-a-clipboard-from-a-background-java-application-on-mac-osx“)和[this](http://stackoverflow.com/questions/ 7717824/cant-monitor-system-clipboard-changes-from-a-background-java-application-on-mac)请参阅m有类似的问题,但在大多数情况下,他们的剪贴板是做数据传输的一种解决方法。我实际上需要一直在阅读剪贴板。 – 2012-04-06 04:58:38

回答

1

我怀疑OSX没有提供剪贴板更改的通知,所以当Java由于某种其他原因而被唤醒时,Java会尽可能地做出最好的通知。

我的怀疑来自NSPasteboard文档,特别是changeCount例程。它说:“因此,您可以在获取纸板所有权时记录更改计数,并将其与changeCount返回的值进行比较,以确定您是否仍拥有所有权。”没有提及使用事件来检测更改。

+0

但是在这种情况下,lostOwnership()方法的确被解雇了,除非它只在将焦点更改为Java应用程序时才会发生。在其他系统上,即使在后台也会触发事件。 – 2012-04-09 08:07:00

+0

我的意思是操作系统不会通知JVM发生更改。 JVM显然会检查changeCount,但只有当它得到一些周期时,比如当它的某个窗口获得焦点时。 – 2012-04-09 18:25:32

0

似乎基思是对的。但是,您可以通过发送应用背景(在* nix)做一个变通方法:

java -jar clipboard-1.0.jar & 

这将打开在后台的Java应用程序,不需要窗口焦点通知解雇。

0

我正试图使用​​这种解决方法,但它不会为我,想法做诡计吗? 注意,现在没有在java中的Mac OS X端口的错误:http://java.net/jira/browse/MACOSX_PORT-511

这是我的源代码:


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

public class ClipboardListener extends Thread implements ClipboardOwner { 

    Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 

    public void run(){ 
     Transferable selection = systemClipboard.getContents(this); 
     gainOwnership(selection); 
     while (true) {} 
    } 

    public void gainOwnership(Transferable t){ 
     try {this.sleep(100);} 
     catch (InterruptedException e) {} 
     systemClipboard.setContents(t, this); 
    } 

    public void lostOwnership(Clipboard clipboard, Transferable contents) { 
     try {System.out.println((String) clipboard.getData(DataFlavor.stringFlavor));} 
     catch (UnsupportedFlavorException e) {} 
     catch (IOException e) {} 
     gainOwnership(contents); 
    } 
} 

public class myApp { 

    public static void main(String[] args){ 
     ClipboardListener listener = new ClipboardListener(); 
     listener.start();} 
} 
相关问题