0

There is such a program. It must analyze the clipboard for the presence of a five-digit number in it. But when you first copy the text that meets the condition, the program works fine, but if you copy the second text in the same window, the program that meets the condition does not work. That is, it works only if you periodically change windows.

The question is to get the program to work with each copy?

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.IOException;

public class Main implements FlavorListener {
    private static Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

    public static void main(String[] args) throws InterruptedException {
        clipboard.addFlavorListener(new Main());

        // fall asleep for 100 seconds, otherwise the program will immediately end

        Thread.sleep(100 * 1000);
    }

    @Override
    public void flavorsChanged(FlavorEvent event) {
        try {
            String clipboardContent = (String) clipboard.getData(DataFlavor.stringFlavor);
            handleClipboardContent(clipboardContent);
        } catch (UnsupportedFlavorException | IOException e) {
            // TODO handle error
            e.printStackTrace();
        }
    }

    private void handleClipboardContent(String clipboardContent) {

        // we check that the length of the string is five
       if (clipboardContent != null && clipboardContent.length() == 5)  
         {


      System.out.println(clipboardContent);
      } 
      else {
        System.out.println("condition false");


        }

    }
}
// 12345
// 56789
  • It looks like you need to learn to use a debugger. Please help yourself to some [complementary debugging techniques](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). If you still have issues afterwards, please feel free to come back with a more specific question. – Joe C Feb 04 '18 at 20:26
  • Look at the naming of the listener method `flavorsChanged` <- This means when the "type" of data changes, if you copy a `String` you get notified, if you copy another `String`, you won't be notified, because it's the same flavour/type of data – MadProgrammer Feb 04 '18 at 20:47
  • The "common" solution to the problem you're facing is to reset the contents of the clipboard to a different flavour. The problem with this is, what happens if some other program wants the data? You've just trampled all over it – MadProgrammer Feb 04 '18 at 20:50

1 Answers1

0

The FlavorListener will notify you when the "type" of data in the Clipboard has changed, not when the data itself has changed. This means if you copy a String to the Clipboard, you "might" be notified, but if you copy another String to the Clipboard, you won't, because the type of data has not changed.

The "common" solution to the problem you're facing is to reset the contents of the clipboard to a different flavour. The problem with this is, what happens if some other program wants the data? You've just trampled all over it

Instead, you could "peek" at the data on a periodical bases and check to see if the contents has changed or not. A basic solution would be to use a Thread which maintained the hashCode of the current String contents, when the hashCode changes, you would then grab a copy and perform what ever operations you wanted on it.

Maybe something like...

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.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

public class Test {

    public static void main(String[] args) {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.addFlavorListener(new FlavorListener() {
            @Override
            public void flavorsChanged(FlavorEvent e) {
                System.out.println("Flavor has changed");
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
                    try {
                        String text = (String) clipboard.getData(DataFlavor.stringFlavor);
                        textDidChangeTo(text);
                    } catch (UnsupportedFlavorException | IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
        Thread t = new Thread(new Runnable() {
            private Integer currentHashcode;
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                    }
                    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                    Transferable contents = clipboard.getContents(this);
                    if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
                        try {
                            String text = (String) clipboard.getData(DataFlavor.stringFlavor);
                            if (currentHashcode == null) {
                                currentHashcode = text.hashCode();
                            } else if (currentHashcode != text.hashCode()) {
                                currentHashcode = text.hashCode();
                                textDidChangeTo(text);
                            }
                        } catch (UnsupportedFlavorException | IOException ex) {
                            ex.printStackTrace();
                        }
                    } else {
                        currentHashcode = null;
                    }
                }
            }
        });
        t.start();
    }

    public static void textDidChangeTo(String text) {
        System.out.println("Text did change to: " + text);
    }
}

Now, this is far from perfect. It may generate two events when the contents changes from something other then String to String. In this, based on your needs, you probably don't need the FlavorListener, but I've used it for demonstration purposes

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366