我在编写一个小的Java程序,该程序可以运行一个外部程序来复制图像到系统剪贴板(即Windows 7的“截图工具”),等待其完成后将剪贴板上的图像保存到磁盘,并将URL(从中可以访问该图像)复制到剪贴板。简而言之,它应该能够:
1. 运行外部工具并等待其返回结果; 2. 从剪贴板中复制一个图像; 3. 将一个字符串复制到剪贴板。
我的程序完全可以实现以上功能。然而,我想要使用Swing/AWT框架来提供用户界面。我正在使用系统托盘图标,但为了简化起见,它也可以是一个JButton在一个框架中。当用户单击按钮时,上述过程应该被执行。第一次执行时,它可以正常工作:图像被复制并粘贴到磁盘中,字符串被复制到剪贴板中。但是,第二次单击按钮时,好像我的程序没有意识到剪贴板已经更新,因为它仍然看到自己在第一次操作时复制的字符串。只有在我的剪贴板处理类失去所有权后,每个操作才会失败。
如果您尝试运行它,会注意到在第二次运行时,只有在尝试复制图像之后才调用lostOwnership方法。我猜这是我的问题的根源,但我不知道为什么会发生这种情况,除非是由Swing事件触发才会发生。希望能得到解决这个问题的任何帮助。
1. 运行外部工具并等待其返回结果; 2. 从剪贴板中复制一个图像; 3. 将一个字符串复制到剪贴板。
我的程序完全可以实现以上功能。然而,我想要使用Swing/AWT框架来提供用户界面。我正在使用系统托盘图标,但为了简化起见,它也可以是一个JButton在一个框架中。当用户单击按钮时,上述过程应该被执行。第一次执行时,它可以正常工作:图像被复制并粘贴到磁盘中,字符串被复制到剪贴板中。但是,第二次单击按钮时,好像我的程序没有意识到剪贴板已经更新,因为它仍然看到自己在第一次操作时复制的字符串。只有在我的剪贴板处理类失去所有权后,每个操作才会失败。
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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main {
private static BufferedImage image; //the image from clipboard to be saved
public static void main(String[] args) throws InterruptedException, IOException {
new GUI();
}
public static void run(String filename) throws IOException, InterruptedException {
CBHandler cbh = new CBHandler();
//run tool, tool will copy an image to system clipboard
Process p = Runtime.getRuntime().exec("C:\\Windows\\system32\\SnippingTool.exe");
p.waitFor();
//copy image from clipboard
image = cbh.getClipboard();
if(image == null) {
System.out.println("No image found in clipboard.");
return;
}
//save image to disk...
//copy file link to clipboard
String link = "http://somedomain.com/" + filename;
cbh.setClipboard(link);
}
}
class CBHandler implements ClipboardOwner {
public BufferedImage getClipboard() {
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
try {
if(t.isDataFlavorSupported(DataFlavor.imageFlavor))
return (BufferedImage) t.getTransferData(DataFlavor.imageFlavor);
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
public void setClipboard(String str) {
StringSelection strsel = new StringSelection(str);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(strsel, this);
}
@Override
public void lostOwnership(Clipboard arg0, Transferable arg1) {
System.out.println("Lost ownership!");
}
}
class GUI extends JFrame {
public GUI() {
JButton button = new JButton("Run");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
try {
Main.run("saveFile.png");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
add(button);
pack();
setVisible(true);
}
}
如果您尝试运行它,会注意到在第二次运行时,只有在尝试复制图像之后才调用lostOwnership方法。我猜这是我的问题的根源,但我不知道为什么会发生这种情况,除非是由Swing事件触发才会发生。希望能得到解决这个问题的任何帮助。