[Chapter 16] Data Transfer

#

| Chapter 16 |

# 16. Data Transfer

Contents:
DataFlavor
Transferable Interface
ClipboardOwner Interface
Clipboard
StringSelection
UnsupportedFlavorException
Reading and Writing the Clipboard

One feature that was missing from Java 1.0 was the ability to access the system clipboard. It was impossible to cut and paste data from one program into another. Java 1.1 includes a package called `java.awt.datatransfer` that supports clipboard operations. Using this package, you can cut an arbitrary object from one program and paste it into another. In theory, you can cut and paste almost anything; in practice, you usually want to cut and paste text strings, so the package provides special support for string operations. The current version allows only one object to be on the clipboard at a time.

`java.awt.datatransfer` consists of three classes, two interfaces, and one exception. Objects that can be transferred implement the `Transferable` interface. The `Transferable` interface defines methods for working with different flavors of an object. The concept of flavors is basic to Java's clipboard model. Essentially, a flavor is a MIME content type. Any object can be represented in several different ways, each corresponding to a different MIME type. For example, a text string could be represented by a Java `String` object, an array of Unicode character data, or some kind of rich text that contains font information. The object putting the string on the clipboard provides whatever flavors it is capable of; an object pasting the string from the clipboard takes whatever flavor it can handle. Flavors are represented by the `DataFlavor` class, and the `UnsupportedFlavorException` is used when an object asks for a `DataFlavor` that is not available.

The `Clipboard` class represents the clipboard itself. There is a single system clipboard, but you can create as many private clipboards as you want. The system clipboard lets you cut and paste between arbitrary applications (for example, Microsoft Word and some Java programs). Private clipboards are useful within a single application, though you could probably figure out some way to export a clipboard to another application using RMI.

To put data on the clipboard, you must implement the `ClipboardOwner` interface, which provides a means for you to be notified when the data you write is removed from the clipboard. (There isn't any `ClipboardReader` interface; any object can read from the clipboard.) The final component of the `datatransfer` package is a special class called `StringSelection` that facilitates cutting and pasting text strings.

Cutting and pasting isn't the whole story; JavaSoft has also promised drag-and-drop capabilities, but this won't be in the initial release of Java 1.1.

## 16.1 DataFlavor

A `DataFlavor` represents a format in which data can be transferred. The `DataFlavor` class includes two common data flavors; you can create other flavors by extending this class. Flavors are essentially MIME content types and are represented by the standard MIME type strings. An additional content subtype has been added to represent Java classes; the content type of a Java object is:[1]

> [1] The type name changed to `x-java-serialized-object` in the 1.1.1 release.

    application/x-java-serialized-object
    <classname>

For example, the content type of a `Vector` object would be:

    application/x-java-serialized-object java.util.Vector

In addition to the content type, a `DataFlavor` also contains a presentable name. The presentable name is intended to be more comprehensible to humans than the MIME type. For example, the presentable name of a `VectorFlavor` object might just be "Vector", rather than the complex and lengthy MIME type given previously. Presentable names are useful when a program needs to ask the user which data flavor to use.

### DataFlavor Methods

Variables

The `DataFlavor` class includes two public variables that hold "prebuilt" flavors representing different kinds of text objects. These flavors are used in conjunction with the `StringSelection` class. Although these flavors are variables for all practical purposes, they are used as constants.

public static DataFlavor stringFlavor

  The `stringFlavor` variable is the data flavor for textual data represented as a Java `String` object. Its MIME type is `application/x-javaserializedobject String`.

public static DataFlavor plainTextFlavor

  The `plainTextFlavor` variable is the data flavor for standard, Unicode-encoded text. Its MIME type is `text/plain; charset=unicode`.

Constructors

The `DataFlavor` class has two constructors. One creates a `DataFlavor` given a MIME content type; the other creates a `DataFlavor` given a Java class and builds the MIME type from the class name.

public DataFlavor(String mimeType, String humanPresentableName)

  The first constructor creates an instance of `DataFlavor` for the `mimeType` flavor of data. The `humanPresentableName` parameter should be a more user-friendly name. It might be used in a menu to let the user select a flavor from several possibilities. It might also be used to generate an error message when the `UnsupportedFlavorException` occurs. The `plainTextFlavor` uses "Plain Text" as its presentable name.

  To read data from the clipboard, a program calls the `Transferable.getTransferData()` method. If the data is represented by a `DataFlavor` that doesn't correspond to a Java class (for example, `plainTextFlavor`), `getTransferData()` returns an `InputStream` for you to read the data from.

public DataFlavor(Class representationClass, String humanPresentableName)

  The other constructor creates an instance of `DataFlavor` for the specific Java class `representationClass`. Again, the `humanPresentableName` provides a more user-friendly name for use in menus, error messages, or other interactions with users. The `stringFlavor` uses "Unicode String" as its presentable name.

  A program calls `Transferable.getTransferData()` to read data from the clipboard. If the data is represented by a Java class, `getTransferData()` returns an instance of the representation class itself. It does not return a `Class` object. For example, if the data flavor is `stringFlavor`, `getTransferData()` returns a `String`.

Presentations

public String getHumanPresentableName()

  The `getHumanPresentableName()` method returns the data flavor's presentable name; for example, `stringFlavor.getHumanPresentableName()` returns the string "Unicode String".

public void setHumanPresentableName(String humanPresentableName)

  The `setHumanPresentableName()` method changes the data flavor's presentable name to a new `humanPresentableName`. It is hard to imagine why you would want to change a flavor's name.

public String getMimeType()

  The `getMimeType()` method gets the MIME content type for the `DataFlavor` as a `String`.

public Class getRepresentationClass()

  The `getRepresentationClass()` method returns the Java type that is used to represent data of this flavor (i.e., the type that would be returned by the `getTransferData()`method). It returns the type as a `Class` object, not an instance of the class itself. Note that all data flavors have a representation class, not just those for which the class is specified explicitly in the constructor. For example, the `plainTextFlavor.getRepresentationClass()` method returns the class `java.io.StringReader`.

public boolean isMimeTypeEqual(String mimeType)

  The `isMimeTypeEqual()` method checks for string equality between `mimeType` and the data flavor's MIME type string. For some MIME types, this comparison may be too simplistic because character sets may not be present on types like `text/plain`. Therefore, this method would tell you that the MIME type `text/plain; charset=unicode` is different from `text/plain`.

public final boolean isMimeTypeEqual(DataFlavor dataFlavor)

  The `isMimeTypeEqual()` method checks whether the MIME type of the `dataFlavor` parameter equals the current data flavor's MIME type. It calls the previous method, and therefore has the same weaknesses.

Protected methods

protected String normalizeMimeType(String mimeType)

  The `normalizeMimeType()` method is used to convert a MIME type string into a standard form. Its argument is a MIME type, as a `String`; it returns the new normalized MIME type. You would never call `normalizeMimeType()` directly, but you might want to override this method if you are creating a subclass of `DataFlavor` and want to change the default normalization process. For example, one thing you might do with this is add the string `charset=US-ASCII` to the `text/plain` MIME type if it appears without a character set.

protected String normalizeMimeTypeParameter(String parameterName, String parameterValue)

  The `normalizeMimeTypeParameter()` method is used to convert any parameters associated with MIME types into a standard form. Its arguments are a parameter name (for example, `charset`) and the parameter's value (for example, `unicode`). It returns `parameterValue` normalized. You would never call `normalizeMimeTypeParameter()` directly, but you might want to override this method if you are creating a subclass of `DataFlavor` and want to change the default normalization process. For example, parameter values may be case sensitive. You could write a method that would convert the value `Unicode` to the more appropriate form `unicode`.

  While it may be more trouble than it's worth, carefully overriding these normalization methods might help you to get more predictable results from methods like `isMimeTypeEqual()`.

Miscellaneous methods

public boolean equals(DataFlavor dataFlavor)

  The `equals()` method defines equality for flavors. Two `DataFlavor` objects are equal if their MIME type and representation class are equal.

The Peer Interfaces |  | Transferable Interface