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
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