Как сохранить JVM во время прослушивания изменений в буфере обмена?
Я пишу программу, которая слушает изменения в буфере обмена и распечатывает изменения в stdout (это всего лишь тест для большой программы). Проблема заключается в том, что, когда основной поток завершает работу, 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);
}
});
}
}
Спасибо!
3 ответа
Как я могу сделать, чтобы JVM работал во время прослушивания буфера обмена?
Я не понимаю, как бы вы сказали программе прекратить прослушивание буфера обмена надлежащим образом.
Я бы просто распечатал какое-то сообщение, используя стандартный вывод с указанием клавиши для выхода из программы, а затем вызвав сканер или аналог для проверки ввода. Таким образом, вы получите 2 важных пункта:
- Нить не умирает сразу, так как сканер выполняет часть ожидания, которую, я думаю, вы ищете.
- Пользователи получают контроль над жизненным циклом потока, поэтому они могут завершить его, когда захотят надлежащим образом
Я бы просто позволил основному потоку спать:
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();
}
}
}
Важно поддерживать по крайней мере один (не-deamon) поток живым, чтобы ваше приложение работало. Живой поток может быть:
- Основная нить, уложить спать
- Новая тема, уложить спать
- Любая ветка приложения awt/swing, которая обычно остается в живых, пока есть хотя бы один нераспределенный элемент
- Любой другой поток, прослушивание любого интерфейса (ожидание
System.in
HTTP-запрос или просто что-нибудь)
Что касается механизма сна, вот мои три разные техники:
Никогда не делайте этого, он будет загружать ваш процессор:
for(;;);
Намерение этого кода ясно видно:
for(;;) Thread.sleep(Long.MAX_VALUE);
Более элегантный:
Object o = new Object(); synchronized (o) {o.wait();}
Смотрите, как вы вешаете поток в Java в одну строку? для обсуждения о сне.
Попробуй это:
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);
}