当复制了一段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("richText", "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;
}
}