Java 剪贴板错误
Java clipboad mistake
有这样的程序。它必须分析剪贴板中是否存在五位数字。但是当你第一次复制满足条件的文本时,程序运行正常,但是如果你在同一个window中复制第二个文本,满足条件的程序就不行了。也就是说,它仅在您定期更改 windows.
时才有效
问题是让程序与每个副本一起工作?
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
FlavorListener
会在 Clipboard
中数据的 "type" 发生变化时通知您,而不是在数据本身发生变化时通知您。这意味着如果您将 String
复制到 Clipboard
,您 "might" 会收到通知,但如果您将另一个 String
复制到 Clipboard
,则不会,因为数据的类型没有改变。
解决您所面临问题的 "common" 解决方案是将剪贴板的内容重置为不同的风格。问题是,如果其他程序想要数据会怎样?你简直把它踩个遍
相反,您可以 "peek" 定期查看数据并检查内容是否已更改。一个基本的解决方案是使用 Thread
来维护当前 String
内容的 hashCode
,当 hashCode
发生变化时,您将获取一个副本并执行任何操作你想要的操作。
也许像...
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);
}
}
现在,这远非完美。当内容从 String
以外的内容更改为 String
时,它可能会生成两个事件。在此,根据您的需要,您可能不需要 FlavorListener
,但我已将其用于演示目的
有这样的程序。它必须分析剪贴板中是否存在五位数字。但是当你第一次复制满足条件的文本时,程序运行正常,但是如果你在同一个window中复制第二个文本,满足条件的程序就不行了。也就是说,它仅在您定期更改 windows.
时才有效问题是让程序与每个副本一起工作?
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
FlavorListener
会在 Clipboard
中数据的 "type" 发生变化时通知您,而不是在数据本身发生变化时通知您。这意味着如果您将 String
复制到 Clipboard
,您 "might" 会收到通知,但如果您将另一个 String
复制到 Clipboard
,则不会,因为数据的类型没有改变。
解决您所面临问题的 "common" 解决方案是将剪贴板的内容重置为不同的风格。问题是,如果其他程序想要数据会怎样?你简直把它踩个遍
相反,您可以 "peek" 定期查看数据并检查内容是否已更改。一个基本的解决方案是使用 Thread
来维护当前 String
内容的 hashCode
,当 hashCode
发生变化时,您将获取一个副本并执行任何操作你想要的操作。
也许像...
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);
}
}
现在,这远非完美。当内容从 String
以外的内容更改为 String
时,它可能会生成两个事件。在此,根据您的需要,您可能不需要 FlavorListener
,但我已将其用于演示目的