当复制了一段richText时,可以在word中粘贴保留有原格式的richText,或者去除了格式信息的plainText;而在notepad中执行粘贴操作时,richText中的格式信息将被过滤,得到的是richText去除格式信息之后的plainText。
问题:
这段richText是以什么样的形式保存在剪贴板中?
执行粘贴操作时应用程序又是如何从剪贴板中取出需要的信息,拆分richText中的格式信息和plainText的呢?
1 java中如何向系统剪贴板写入一段plainText。
这是最基本的Clipboard操作,操作非常直观,java API已经直接提供了白痴级的支持:
Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); StringSelection stringSelection = new StringSelection("plainText"); systemClipboard.setContents(stringSelection, null);
事情总是如此,初识时美好,当进一步了解时,便会有障碍。
当我们对Clipboard的操作有了新的要求,便只能硬着头皮去掌握应用程序和Clipboard之间的数据传输原理。怎么学习呢,网上资料不算多,最好不过还是直接看API了,但问题在于API向来言简意赅,这一段的API更是比较晦涩,而其中一些类、方法的实现方式与本人的代码习惯很是不符,看起来很是不能理解。
软件包 java.awt.datatransfer
提供在应用程序之间和在应用程序内部传输数据的接口和类,接口和类不算多,基础的、重要的有2个:
public interface Transferable
定义为传输操作提供数据所使用的类的接口,我们要在剪贴板和应用程序之间传输的数据就是放在这玩意中了。
public class DataFlavor
extends Object
implements Externalizable, Cloneable
DataFlavor 提供有关数据的元信息。DataFlavor 通常用于访问剪切板上的数据,或者在执行拖放操作时使用。
我们要传输的数据存储于Transferable对象之中,如何存储?
Transferable是一个接口,在此接口的具体实现中,我们要传输的数据便可作为类的属性存储其中。
如何取出?
这是问题的难点。在从Transferable中取出数据的过程中,我认为DataFlavor将扮演一个存储数据的标识和解析器的角色:作为标识,Transferable会根据应用程序提供的DataFlavor类型向应用程序返回特定的数据,在某种情况下,你可以认为DataFlavor和存储数据之间存在映射关系;作为解析器,当应用程序从Transferable中取得数据之后,将同时使用提取数据时传入Transferable的DataFlavor来进行数据解析,在同一个JVM中,这是容易处理的,当在不同的JVM,或者JVM和本地应用程序之间传输数据时,这意味着JVM的DataFlavor和系统的DataFlavor存在一种映射关系。
直接上例子:
package com.dancen.test; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; /** * 剪贴板操作示例 * * @author Dancen * */ public class ClipboardDemo { public static void main(String[] args) { try { Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable transferable = new TextTransferable("<html><body><font color=FF0000>richText</font></body></html>", "plainText"); systemClipboard.setContents(transferable, null); } catch(Exception e) { e.printStackTrace(); } } } class TextTransferable implements Transferable { public final static DataFlavor PLAIN_TEXT_DF; public final static DataFlavor RICH_TEXT_DF; private final static DataFlavor[] DFS; private String richText; private String plainText; static { PLAIN_TEXT_DF = DataFlavor.stringFlavor; RICH_TEXT_DF = new DataFlavor("text/html; charset=unicode; class=java.lang.String", "text/html"); DFS = new DataFlavor[]{PLAIN_TEXT_DF, RICH_TEXT_DF}; } public TextTransferable(String richText, String plainText) { if(null == plainText) { throw new IllegalArgumentException("the plainText can not be null"); } if(null == richText) { richText = plainText; } this.richText = richText; this.plainText = plainText; } @Override public boolean isDataFlavorSupported(DataFlavor dataFlavor) { boolean rs = false; for(DataFlavor df : DFS) { if(df.equals(dataFlavor)) { rs = true; break; } } return rs; } @Override public DataFlavor[] getTransferDataFlavors() { return DFS.clone(); } @Override public Object getTransferData(DataFlavor dataFlavor) throws UnsupportedFlavorException, IOException { String rs = null; if(PLAIN_TEXT_DF.equals(dataFlavor)) { rs = this.plainText; } else if(RICH_TEXT_DF.equals(dataFlavor)) { rs = this.richText; } else { throw new UnsupportedFlavorException(dataFlavor); } return rs; } }