Java线程在没有关注OSX时进入hibernate状态

我正在编写一个程序来监听系统剪贴板的更改。 侦听器在单独的线程上运行,并在剪贴板的内容发生更改时执行某些操作(例如,写入文件)。

我正在使用ClipboardOwner接口轮询剪贴板,这样当我的程序失去剪贴板的所有权(意味着另一个进程已经修改了剪贴板)时,我的程序中会触发一个事件让我读取更改。

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 */ } } 

问题是,当在OS​​X中运行时,只有当我手动Cmd-Tab到Dock中正在运行的进程图标时,才会反映对剪贴板的任何更改。 因此,如果在切换到停靠图标之前有多个剪贴板操作,则只有最后一个具有任何效果。 我在Linux或Windows上没有遇到这个问题。

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

我怀疑OSX没有提供剪贴板更改的通知,因此Java会因为其他原因被唤醒时通知您。

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

似乎基思是对的。 但是,您可以通过将应用程序发送到后台(在* Nix上)来执行解决方法:

 java -jar clipboard-1.0.jar & 

这将在后台打开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();} }