如何用Java操作剪贴板? 目前只能实现纯文本的复制,如何实现类似DreamWeaver的图片的url复制?谢谢。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 请参考JAVA 2 图形设计卷:第20章 剪贴板与数据传输其中一部分:20.6.1 ImageSelection——封装图像的Transferable对象 实现图像复制操作首先需要处理的问题是开发一个类,它实现Transferable对象并封装图像。这个类的第一个版本中,将仅仅实现图像的一种表示格式,即java.awt.image。随后,为了更好地使用,我们将增加另一外一种数据格式。 我们遵循StringSelection的命名约定,将我们需要创建的类命名为ImageSelection。另外,与StringSelection相同,为了使用方便,我们将实现ClipboardOwner接口(注:请参阅20.2.2节“ClipboardOwnerod ”。实现Transferable的类也同时实现ClipboardOwner接口是经常使用的处理方法),这样当设置剪贴板内容时可以将其内容与剪贴板拥有者指定为同一个对象: public class imageSelection implements Transferable,ClipboardOwner{ static public DataFlavor imageFlavor; private DataFlavor[] flavors={imageFlavor}; private Image image; ... ImageSelection 包含DataFlavor的一个静态公共实例,客户可利用该实例指定图像按照哪种数据格式产生。既然ImageSelection只提供一种图像数据格式,其数据格式数组中将仅仅只包含一个项目。当然,调用getTransferDataFlavor方法可以返回该数组。最后,ImageSelection保持它当前代表的图像的引用。 ImageSelection实现一个创建ImageFlavor实例的静态块: static{ try{ ImageFlavor=new DataFlavor( Class.forName("java.awt.Image"),"AWT Image"); } catch(ClassNotFoundException e){ e.printStackTrace(); } } 数据格式是利用Java类创建的,而不是利用MIME类创建的。另外,数据格式被命名为具有标识意义的“AWT Image”。 ImageSelection提供唯一个构造器,它使用图像的引用,实现Transferable接口所需要的3个方法: public ImageSelection(Image image) { this.image = image; } public synchronized DataFlavor[] getTransferDataFlavors() { return flavors; } public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(ImageFlavor); } public synchronized Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if(flavor.equals(ImageFlavor)) { return image; } else { throw new UnsupportedFlavorException(flavor); } } public void lostOwnership(Clipboard c, Transferable t) { } 如果getTransferData()请求的数据格式与ImageFlavor实例相等,则返回图像。否则,将抛出一个异常UnsupportedFlavorException另外,由于在这种情况下,ImageSelection永远不会释放与其封装图像相关的资源,因此,其lostOwnership方法被实现为空操作方法。 至此,已经完成了封装图像的Transferable对象。ImageSelection类的完整代码如程序范例20-2所示。 程序范例20-2 ImageSelection类 import java.awt.*; import java.awt.datatransfer.*; import java.io.*; public class ImageSelection implements Transferable, ClipboardOwner { static public DataFlavor ImageFlavor; private DataFlavor[] flavors = {ImageFlavor}; private Image image; static { try { ImageFlavor = new DataFlavor( Class.forName("java.awt.Image"), "AWT Image"); } catch(ClassNotFoundException e) { e.printStackTrace(); } catch(java.util.mime.MimeTypeParseException e) { e.printStackTrace(); } } public ImageSelection(Image image) { this.image = image; } public synchronized DataFlavor[] getTransferDataFlavors() { return flavors; } public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(ImageFlavor); } public synchronized Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if(flavor.equals(ImageFlavor)) { return image; } else { throw new UnsupportedFlavorException(flavor); } } public void lostOwnership(Clipboard c, Transferable t) { } } 现在,我们将通过介绍把图像复制到局部剪贴板再取出图像的程序范例,介绍ImageSelection类的使用。 20.6.2 使用ImageSelection类 如图20-4所示,这个applet中包含两个图像画布、一个“Copy”按钮以及一个“Panel”按钮。其中一个画布中初始时包含一个图像。单击“Copy”按钮可以将图像复制到剪贴板,本例中将图像复制到局部剪贴板,而不是复制到系统剪贴板。随后再单“Paste”按钮则可从局部剪贴板中取出图像并将其放置到右侧的图像画布中。 public class ClipboardTest2 extends Applet implements ClipboardOwner { private Clipboard clipboard; private ImageCanvas copyFrom = new ImageCanvas(); private ImageCanvas copyTo = new ImageCanvas(); private Button copy = new Button("Copy"); private Button paste = new Button("Paste"); public void init() { clipboard = new Clipboard("image clipboard"); copyFrom.setImage(getImage(getCodeBase(),"skelly.gif")); add(copyFrom); add(copyTo); add(copy); add(paste); copy.addActionListener (new CopyListener()); paste.addActionListener(new PasteListener()); } ... } 其次,分别实现两个按钮的事件监听者 class CopyListener implements ActionListener { public void actionPerformed(ActionEvent event) { ImageSelection contents = new ImageSelection(copyFrom.getImage()); clipboard.setContents(contents, ClipboardTest2.this); } } class PasteListener implements ActionListener { public void actionPerformed(ActionEvent event) { Transferable contents = clipboard.getContents(this); if(contents != null && contents.isDataFlavorSupported( ImageSelection.ImageFlavor)) { try { Image image; image = (Image) contents.getTransferData( ImageSelection.ImageFlavor); copyTo.setImage(image); } catch(Exception e) { e.printStackTrace(); } } } } CopyListener.actionPerformed()方法创建ImageSelection实例,它将被放置到剪贴板上。由于CopyListener是ClipboardTest2的一个内部类,而且是CopyListener实现ClipboardOwner接口,而不是ClipboardTest2实现ClipboardOwner接口,因此剪贴板拥有者(setContents()方法中的第二个参数)被指定为ClipboardTest2.this。 获取剪贴板内容后,PasteListener.actionPerformed()方法将检查剪贴板上的当前Transferable对象是否支持ImageSelection.ImageFlavor数据格式。很显然,就本例而言,这一个判断步骤是多余的。因为我们知道是谁将数据放置到剪贴板上,因此我们可以肯定Transferable对象支持ImageSelection.ImageFlavor数据格式。但是复制到剪贴板上的对象与从剪贴板取出的对象之间并不能永远保持本例所示的这种紧耦合关系,因此为了说明整个程序范例的完整步骤,我们实现了数据格式检查步骤。最后,我们从Transferable对象中取图像,并将其放置到右侧的图像画布中。 整个的applet代码,请参见下面的程序范例20-3。其中,ImageCanvas的实现代码与我们正强调的概念之间没有丝毫关系,但是为了保持代码完整,我们仍将其包含在程序范例20-3中。 程序范例20-3 ClipboardTest2 Applet import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.awt.datatransfer.*; public class ClipboardTest2 extends Applet implements ClipboardOwner { private Clipboard clipboard; private ImageCanvas copyFrom = new ImageCanvas(); private ImageCanvas copyTo = new ImageCanvas(); private Button copy = new Button("Copy"); private Button paste = new Button("Paste"); public void init() { clipboard = new Clipboard("image clipboard"); copyFrom.setImage(getImage(getCodeBase(),"skelly.gif")); add(copyFrom); add(copyTo); add(copy); add(paste); copy.addActionListener (new CopyListener()); paste.addActionListener(new PasteListener()); } class CopyListener implements ActionListener { public void actionPerformed(ActionEvent event) { ImageSelection contents = new ImageSelection(copyFrom.getImage()); clipboard.setContents(contents, ClipboardTest2.this); } } class PasteListener implements ActionListener { public void actionPerformed(ActionEvent event) { Transferable contents = clipboard.getContents(this); if(contents != null && contents.isDataFlavorSupported( ImageSelection.ImageFlavor)) { try { Image image; image = (Image) contents.getTransferData( ImageSelection.ImageFlavor); copyTo.setImage(image); } catch(Exception e) { e.printStackTrace(); } } } } public void lostOwnership(Clipboard clip, Transferable transferable) { System.out.println("Lost ownership"); } } class ImageCanvas extends Panel { private Image image; public ImageCanvas() { this(null); } public ImageCanvas(Image image) { if(image != null) setImage(image); } public void paint(Graphics g) { g.setColor(Color.lightGray); g.draw3DRect(0,0,getSize().width-1, getSize().height-1,true); if(image != null) { g.drawImage(image, 1, 1, this); } } public void update(Graphics g) { paint(g); } public void setImage(Image image) { this.image = image; try { MediaTracker tracker = new MediaTracker(this); tracker.addImage(image, 0); tracker.waitForID(0); } catch(Exception e) { e.printStackTrace(); } if(isShowing()) { repaint(); } } public Image getImage() { return image; } public Dimension getPreferredSize() { return new Dimension(100,100); } } PreparedStatement问题 报数出局问题,谁来分析下算法! 数据结构:树形结构的问题。 [闭月羞花猫]这两天怎么这么忙? java中是否提供了对串口进行打操作的类!! 请问如何在finally中得到前面try或catch中抛出的异常? protected是这样吗? 怎样往一个已存在的文件末尾加入新的内容? JAVA里如何进行类型转换? tcp中的不理解 swing问题求助 请问ResultSet.TYPE_SCROLL_SENSITIVE和ResultSet.TYPE_SCROLL_INSENSITIVE的区别
其中一部分:
20.6.1 ImageSelection——封装图像的Transferable对象 实现图像复制操作首先需要处理的问题是开发一个类,它实现Transferable对象并封装图像。这个类的第一个版本中,将仅仅实现图像的一种表示格式,即java.awt.image。随后,为了更好地使用,我们将增加另一外一种数据格式。
我们遵循StringSelection的命名约定,将我们需要创建的类命名为ImageSelection。另外,与StringSelection相同,为了使用方便,我们将实现ClipboardOwner接口(注:请参阅20.2.2节“ClipboardOwnerod ”。实现Transferable的类也同时实现ClipboardOwner接口是经常使用的处理方法),这样当设置剪贴板内容时可以将其内容与剪贴板拥有者指定为同一个对象: public class imageSelection implements Transferable,ClipboardOwner{
static public DataFlavor imageFlavor;
private DataFlavor[] flavors={imageFlavor};
private Image image;
... ImageSelection 包含DataFlavor的一个静态公共实例,客户可利用该实例指定图像按照哪种数据格式产生。既然ImageSelection只提供一种图像数据格式,其数据格式数组中将仅仅只包含一个项目。当然,调用getTransferDataFlavor方法可以返回该数组。最后,ImageSelection保持它当前代表的图像的引用。
ImageSelection实现一个创建ImageFlavor实例的静态块:
static{
try{
ImageFlavor=new DataFlavor(
Class.forName("java.awt.Image"),"AWT Image");
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
} 数据格式是利用Java类创建的,而不是利用MIME类创建的。另外,数据格式被命名为具有标识意义的“AWT Image”。
ImageSelection提供唯一个构造器,它使用图像的引用,实现Transferable接口所需要的3个方法: public ImageSelection(Image image) {
this.image = image;
}
public synchronized DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(ImageFlavor);
}
public synchronized Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if(flavor.equals(ImageFlavor)) {
return image;
}
else {
throw new UnsupportedFlavorException(flavor);
}
}
public void lostOwnership(Clipboard c, Transferable t) {
}
如果getTransferData()请求的数据格式与ImageFlavor实例相等,则返回图像。否则,将抛出一个异常UnsupportedFlavorException另外,由于在这种情况下,ImageSelection永远不会释放与其封装图像相关的资源,因此,其lostOwnership方法被实现为空操作方法。
至此,已经完成了封装图像的Transferable对象。ImageSelection类的完整代码如程序范例20-2所示。 程序范例20-2 ImageSelection类 import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*; public class ImageSelection implements Transferable,
ClipboardOwner {
static public DataFlavor ImageFlavor; private DataFlavor[] flavors = {ImageFlavor};
private Image image; static {
try {
ImageFlavor = new DataFlavor(
Class.forName("java.awt.Image"), "AWT Image");
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
catch(java.util.mime.MimeTypeParseException e) {
e.printStackTrace();
}
}
public ImageSelection(Image image) {
this.image = image;
}
public synchronized DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(ImageFlavor);
}
public synchronized Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if(flavor.equals(ImageFlavor)) {
return image;
}
else {
throw new UnsupportedFlavorException(flavor);
}
}
public void lostOwnership(Clipboard c, Transferable t) {
}
}
implements ClipboardOwner {
private Clipboard clipboard;
private ImageCanvas copyFrom = new ImageCanvas();
private ImageCanvas copyTo = new ImageCanvas();
private Button copy = new Button("Copy");
private Button paste = new Button("Paste"); public void init() {
clipboard = new Clipboard("image clipboard"); copyFrom.setImage(getImage(getCodeBase(),"skelly.gif"));
add(copyFrom);
add(copyTo);
add(copy);
add(paste); copy.addActionListener (new CopyListener());
paste.addActionListener(new PasteListener());
}
...
} 其次,分别实现两个按钮的事件监听者 class CopyListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
ImageSelection contents =
new ImageSelection(copyFrom.getImage());
clipboard.setContents(contents, ClipboardTest2.this);
}
}
class PasteListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
Transferable contents = clipboard.getContents(this); if(contents != null &&
contents.isDataFlavorSupported(
ImageSelection.ImageFlavor)) {
try {
Image image;
image = (Image) contents.getTransferData(
ImageSelection.ImageFlavor);
copyTo.setImage(image);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}
CopyListener.actionPerformed()方法创建ImageSelection实例,它将被放置到剪贴板上。由于CopyListener是ClipboardTest2的一个内部类,而且是CopyListener实现ClipboardOwner接口,而不是ClipboardTest2实现ClipboardOwner接口,因此剪贴板拥有者(setContents()方法中的第二个参数)被指定为ClipboardTest2.this。
获取剪贴板内容后,PasteListener.actionPerformed()方法将检查剪贴板上的当前Transferable对象是否支持ImageSelection.ImageFlavor数据格式。很显然,就本例而言,这一个判断步骤是多余的。因为我们知道是谁将数据放置到剪贴板上,因此我们可以肯定Transferable对象支持ImageSelection.ImageFlavor数据格式。但是复制到剪贴板上的对象与从剪贴板取出的对象之间并不能永远保持本例所示的这种紧耦合关系,因此为了说明整个程序范例的完整步骤,我们实现了数据格式检查步骤。最后,我们从Transferable对象中取图像,并将其放置到右侧的图像画布中。
整个的applet代码,请参见下面的程序范例20-3。其中,ImageCanvas的实现代码与我们正强调的概念之间没有丝毫关系,但是为了保持代码完整,我们仍将其包含在程序范例20-3中。 程序范例20-3 ClipboardTest2 Applet import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*; public class ClipboardTest2 extends Applet
implements ClipboardOwner {
private Clipboard clipboard;
private ImageCanvas copyFrom = new ImageCanvas();
private ImageCanvas copyTo = new ImageCanvas();
private Button copy = new Button("Copy");
private Button paste = new Button("Paste"); public void init() {
clipboard = new Clipboard("image clipboard"); copyFrom.setImage(getImage(getCodeBase(),"skelly.gif"));
add(copyFrom);
add(copyTo);
add(copy);
add(paste); copy.addActionListener (new CopyListener());
paste.addActionListener(new PasteListener());
}
class CopyListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
ImageSelection contents =
new ImageSelection(copyFrom.getImage());
clipboard.setContents(contents, ClipboardTest2.this);
}
}
class PasteListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
Transferable contents = clipboard.getContents(this); if(contents != null &&
contents.isDataFlavorSupported(
ImageSelection.ImageFlavor)) {
try {
Image image;
image = (Image) contents.getTransferData(
ImageSelection.ImageFlavor);
copyTo.setImage(image);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}
public void lostOwnership(Clipboard clip,
Transferable transferable) {
System.out.println("Lost ownership");
}
}
class ImageCanvas extends Panel {
private Image image; public ImageCanvas() {
this(null);
}
public ImageCanvas(Image image) {
if(image != null)
setImage(image);
}
public void paint(Graphics g) {
g.setColor(Color.lightGray); g.draw3DRect(0,0,getSize().width-1,
getSize().height-1,true); if(image != null) {
g.drawImage(image, 1, 1, this);
}
}
public void update(Graphics g) {
paint(g);
}
public void setImage(Image image) {
this.image = image;
try {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(image, 0);
tracker.waitForID(0);
}
catch(Exception e) { e.printStackTrace(); } if(isShowing()) {
repaint();
}
}
public Image getImage() {
return image;
}
public Dimension getPreferredSize() {
return new Dimension(100,100);
}
}