2016-10-24 11 views
3

Я пишу программу, которая прослушивает изменения в буфере обмена и печатает, что изменяется на stdout (это просто тест для более крупной программы). Проблема в том, что когда основной поток заканчивается, JVM выходит и никакие события не поступают к слушателю. Как сделать, чтобы JVM работал во время прослушивания буфера обмена?Java - Как сохранить работу 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); 
      } 
     }); 

    } 

} 

Спасибо!

+1

когда-либо слышало Threading? https://en.wikipedia.org/wiki/Thread_(computing) – Olayinka

+1

@ Олайинка, какая связь с вопросом OP? Я бы предположил, что 'Clipboard' обрабатывает его слушателей, и поэтому потоки не должны быть проблемой здесь. – Turing85

+0

@ Turing85 Я думаю, вы правы. Я уверен, что, если ОП поймет концепцию потоки, он узнает, почему процесс выходит и не остался в живых, как ему хотелось. – Olayinka

ответ

3

Как сделать, чтобы JVM работал при прослушивании буфера обмена?

Я не вижу, как вы сказали бы программе прекратить слушать буфер обмена надлежащим образом.

Что бы я сделал, это просто напечатать какое-то сообщение с использованием стандартного вывода, указывающего ключ для выхода из программы, а затем вызов сканера или аналогичный для проверки ввода.Таким образом, вы достигаете 2 важных моментов:

  1. Нить не умирает сразу, так как сканер выполняет «ожидающую» часть, я думаю, что вы ищете.
  2. Пользователи получают контроль над жизненным циклом потока, так что они могут прекратить его всякий раз, когда они хотят должным образом
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) нить живой, чтобы сохранить вашу работу приложения. Живой поток может быть:

  1. основной нить, усыпила
  2. A новой нити, положить спать
  3. Любой AWT/Swing потока приложения, которые будут обычно работает на жидком остаться в живых , если существует хотя бы один элемент, не содержащий
  4. Любые другие темы, прослушивание на любой интерфейс (ожидание System.in, HTTP-запрос или просто что-либо)

Что касается механизма сна, вот мои три различных Методика:

  1. Никогда не делайте этого, он будет держать ваш процессор занят:

    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? для обсуждения сна.

+0

Говоря о «любой» теме, важно иметь в виду разницу между потоками daemon и non-daemon. – biziclop

+0

, и вы можете позволить потоку «спать», вызывая '.wait()' на каком-либо объекте (например, 'Test'). – Turing85

+0

@biziclop Вы абсолютно правы в потоках деамонов - я обновил свой ответ. Благодаря! – slartidan

0

Попробуйте это:

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); 
}