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.
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
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.
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:
For example, the content
type of a Vector object would
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.
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
- public static DataFlavor plainTextFlavor
The plainTextFlavor variable
is the data flavor for standard, Unicode-encoded text. Its MIME type is
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
returns a String.
- 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)
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()
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 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
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
- 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.