当没有关注OSX时,Java线程进入休眠状态

时间:2012-04-06 04:52:46

标签: java multithreading macos clipboard

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

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

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上没有遇到这个问题。

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

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

java -jar clipboard-1.0.jar &

这将在后台打开Java应用程序,并且不需要窗口焦点来触发通知。

答案 2 :(得分:0)

我试图使用这种解决方法,但它不能为我做这些诀窍,想法? 请注意,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();}
}