listen to clipboard changes, check ownership?

前端 未结 3 1718
北海茫月
北海茫月 2020-12-06 13:33

I want to be notified if a string is copied to the system clipboard. When a new string is copied from the same source application, the FlavorListener won\'t get an event. To

相关标签:
3条回答
  • 2020-12-06 14:04

    To avoid double notification remove the flavor listener before setting the new clipboard content and add the listener again after setting clipboard content.

    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");
        }
    }
    
    0 讨论(0)
  • 2020-12-06 14:17

    The previous answer is close to be working.

    The real cure is to instead just monitor the event of ownership change. By the monitor's occupying the clipboard as owner when monitoring the clipboard, so when any application changes the clipboard, the ownership would change, so this would reliably indicate the clipboard content change. However, this approach must have sufficient wait to work, (200 ms was found to be working) after an ownership change event before accessing the clipboard and re-occupying the clipboard.

    This solution was provided and proved to be working by marc weber at http://www.coderanch.com/t/377833/java/java/listen-clipboard

    I have verified for my purpose. If needed, I can post the solution here.

    Yu

    0 讨论(0)
  • 2020-12-06 14:24

    I think this would work :)

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

    }

    0 讨论(0)
提交回复
热议问题