Java - 如何在监听剪贴板更改时保持 JVM 运行?

Java - How to keep JVM running while listening to clipboard changes?

我正在编写一个程序来侦听剪贴板更改并将更改打印到标准输出(这只是对更大程序的测试)。问题是:当主线程结束时,JVM 退出并且没有事件到达侦听器。如何在监听剪贴板时保持 JVM 运行?

我的代码如下所示:

public class Test {

    public static void main(String[] args) {

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

        cb.addFlavorListener(new FlavorListener() {
            @Override
            public void flavorsChanged(FlavorEvent e) {
                System.out.println(e);
            }
        });

    } 

}

谢谢!

我会让主线程休眠:

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;

public class Test {

    public static void main(String[] args) throws InterruptedException {

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

        cb.addFlavorListener(new FlavorListener() {
            @Override
            public void flavorsChanged(FlavorEvent e) {
                System.out.println(e);
            }
        });

        // sleep forever
        Object o = new Object();
        synchronized (o) {
            o.wait();
        }
    } 
}

保持 至少一个 (非守护程序)线程处于活动状态非常重要,以保持您的应用程序 运行。活动线程可能是:

  1. main线程,进入休眠状态
  2. 一个线程,进入休眠状态
  3. 任何 awt/swing 应用程序线程,通常会保持活动状态,只要至少有一个未处理的元素
  4. 任何其他线程,侦听任何接口(等待System.in、HTTP-Request 或任何东西)

关于睡眠机制,这里是我的三种不同技术:

  1. 永远不要这样做,它会让你的CPU忙碌:

    for(;;);
    
  2. 这段代码的用意可见一斑:

    for(;;) Thread.sleep(Long.MAX_VALUE);
    
  3. 更优雅:

    Object o = new Object();
    synchronized (o) {o.wait();}
    

有关睡眠的讨论,请参阅 How do you hang a thread in Java in one line?

How can I do to keep JVM running while listening the clipboard?

我不明白你会如何以正确的方式告诉程序停止监听剪贴板。

我要做的只是使用标准输出打印某种消息,指示退出程序的键,然后调用扫描仪或类似程序来检查输入。通过这种方式,您可以获得 2 个要点:

  1. 当扫描程序执行我认为您正在寻找的 "wait" 部分时,线程不会立即终止。
  2. 用户可以控制线程的生命周期,因此他们可以随时以适当的方式终止它

试试这个:

public static void listen() throws InterruptedException {
    Thread t = new Thread (new Runnable(){

        @Override
        public void run() {
            Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
            Transferable contents = cb.getContents(null);
            cb.addFlavorListener(new FlavorListener() {
                @Override
                public void flavorsChanged(FlavorEvent e) {
                    try {
                        System.out.println("Got Data:"+(String)contents.getTransferData(DataFlavor.stringFlavor));
                    } catch (UnsupportedFlavorException | IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            });
        }
    });
    t.setDaemon(true);
    t.start();

    while (true)
        Thread.sleep(Long.MAX_VALUE);
}