听剪贴板更改,检查所有权?

如果将字符串复制到系统剪贴板,我希望收到通知。 从同一源应用程序复制新字符串时,FlavorListener将不会获取事件。 为了在复制另一个字符串时获得通知,我从剪贴板中读取字符串,将其转换为SrtingSelection,它可以获取所有权,并将其放回剪贴板。 现在,一旦StringSelection失去了所有权并且一旦收回它,我就得到了两次通知。 有没有办法直接检查所有权,而不是存储字符串并检查它是否等于新的? 这是我到目前为止的代码:

import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.FlavorEvent; import java.awt.datatransfer.FlavorListener; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; public class Main { public static void main(String[] args) throws Exception { // The clipboard final Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); // read clipboard and take ownership to get the FlavorListener notified // when the content has changed but the owner has not processClipboard(cb); cb.addFlavorListener(new FlavorListener() { @Override public void flavorsChanged(FlavorEvent e) { processClipboard(cb); } }); // keep thread for testing Thread.sleep(100000L); } public static void processClipboard(Clipboard cb) { // gets the content of clipboard Transferable trans = cb.getContents(null); if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) { try { // cast to string String s = (String) trans .getTransferData(DataFlavor.stringFlavor); System.out.println(s); // only StringSelection can take ownership, i think StringSelection ss = new StringSelection(s); // set content, take ownership cb.setContents(ss, ss); } catch (UnsupportedFlavorException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } } } } 

我希望你理解我的坏英语:-(

之前的答案即将开始。

真正的解决方法是只监控所有权变更事件。 监视器在监视剪贴板时占用剪贴板作为所有者,因此当任何应用程序更改剪贴板时,所有权将更改,因此这将可靠地指示剪贴板内容更改。 但是,在访问剪贴板并重新占用剪贴板之前,在所有权更改事件之后,此方法必须有足够的等待工作(发现200毫秒工作)。

提供此解决方案并certificate由marc weber在http://www.coderanch.com/t/377833/java/java/listen-clipboard上工作

我已经validation了我的目的。 如果需要,我可以在这里发布解决方案。

要避免双重通知,请在设置新剪贴板内容之前删除flavor侦听器,并在设置剪贴板内容后再次添加侦听器。

 public class NewClass implements FlavorListener, ClipboardOwner{ private Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); public NewClass() { System.out.println("NewClass constructor"); clip.setContents(clip.getContents(null), this); clip.addFlavorListener(this); try { Thread.sleep(100000L); } catch (InterruptedException e) { } } @Override public void flavorsChanged(FlavorEvent e) { System.out.println("ClipBoard Changed!!!"); clip.removeFlavorListener(this); clip.setContents(clip.getContents(null), this); clip.addFlavorListener(this); } @Override public void lostOwnership(Clipboard arg0, Transferable arg1) { System.out.println("ownership losted"); } } 

我认为这会奏效:)

 import java.awt.AWTEvent; import java.awt.EventQueue; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.io.IOException; import java.util.Observable; import java.util.Observer; import javax.swing.JFrame; public final class ClipboardMonitor extends Observable implements ClipboardOwner { private static ClipboardMonitor monitor = null; public ClipboardMonitor() { gainOwnership(); } private void gainOwnership() { Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); try { Transferable content = clip.getContents(null); DataFlavor[] f = content.getTransferDataFlavors(); boolean imageDetected = false; for (int i = 0; i < f.length; i++) { // System.out.println("Name: " + f[i].getHumanPresentableName()); // System.out.println("MimeType: " + f[i].getMimeType()); // System.out.println("PrimaryType: " + f[i].getPrimaryType()); // System.out.println("SubType: " + f[i].getSubType()); if (f[i].equals(DataFlavor.imageFlavor)) { imageDetected = true; break; } } if (imageDetected) { System.out.println("Image content detected"); Transferable t = new Transferable() { public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.stringFlavor }; } public boolean isDataFlavorSupported(DataFlavor flavor) { return false; } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return "dummy text instead of snapshot image"; } }; clip.setContents(t, this); } else { clip.setContents(content, this); } setChanged(); notifyObservers(content); } catch (IllegalArgumentException istateexception) { istateexception.printStackTrace(); } catch (Exception ioexception) { ioexception.printStackTrace(); } } private int getCurrentEventModifiers() { int modifiers = 0; AWTEvent currentEvent = EventQueue.getCurrentEvent(); if (currentEvent instanceof InputEvent) { modifiers = ((InputEvent) currentEvent).getModifiers(); } else if (currentEvent instanceof ActionEvent) { modifiers = ((ActionEvent) currentEvent).getModifiers(); } return modifiers; } public void lostOwnership(Clipboard clipboard, Transferable contents) { System.out.println("Ownership lost ..."); new Thread(new Runnable() { public void run() { try { Thread.sleep(200); gainOwnership(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } public void flushClipboard() { Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(""), null); } public static final ClipboardMonitor getMonitor() { if (monitor == null) monitor = new ClipboardMonitor(); return (monitor); } public static void main(String[] args) { JFrame f = new JFrame(); ClipboardMonitor monitor = ClipboardMonitor.getMonitor(); monitor.addObserver(new Observer() { public void update(Observable o, Object arg) { System.out.println("Clipboard has been regained!"); } }); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(500, 100); f.setVisible(true); } 

}