Inside Java

Using the clipboard with Java 1.1


 

Introduction

Java 1.1 contains a package in java.awt.datatransfer that supports clipboard operations. There are three classes, and two interfaces in this package. Using those objects, you can cut and paste everything.

Some useful types are already implemented. They are strings and plain text. But objects that can be transferred implement the Transferable interface. This interface defines different flavors for the same object. For example, let's consider a Word document that contains text and images. A flavor of this document could be the text contained, or the images, or the document itself. This mechanism is very powerful. A object can be represented in several ways (the flavors) using a MIME Type, and a Human readable type.

Flavors are represented by the DataFlavor class. There are two useful flavors already built. They are defined statically in the DataFlavor class: stringFlavor and plainTextFlavor.

You can create a clipboard using the Clipboard class, or you can even use the system Clipboard using getToolkit().getSystemClipboard(). An object that needs to put data on a clipboard implements the ClipboarOwner interface.

An example

This example uses two text areas and two buttons. Type some text in the first TextArea, select some text, then hit "Copy". Click inside the other TextArea, then press "Paste'.

You can download the whole example:

This example uses 1.1 features (Clipboard, event listeners).
We create a clipboard. When the "Cut" button is pressed, a Transferable object is created with the Transfer class using the selection in the first TextArea. It's send to the clipboard.

Then, when the "Paste" button is pressed, we read the content of the Clipboard. We try to determine if the object stored in the Clipboard supports "text/insidejava" MIME type and stringFlavor (already implemented in DataFlavor).

The isDataFlavorSupported method in the Transfer class is called, and should return true. Then we simply get the content of the object, we cast it because we know it corresponds to "text/insidejava", and paste it in the second TextArea.

The getTransferFlavors() method returns a sorted array of DataFlavors supported by the Transferable object. The most important Flavor should be the first element.

The most important thing to remember here is the mechanism used to figure out what MIME type a Transferable object supports. The interesting part of the code is in red.

Here is the source code:

import java.net.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;
import java.awt.event.*;

class clipboard extends Frame implements ClipboardOwner{
    TextArea t1=new TextArea("Area 1...",20,20);
    TextArea t2=new TextArea("Area 2...",20,20);
    Button b1=new Button("Copy");
    Button b2=new Button("Paste");
    Panel pA=new Panel();
    Panel pB=new Panel();
    ClipboardOwner owner=this;
    Clipboard Clip=new Clipboard("Inside Java");
   
    public void lostOwnership(Clipboard b,Transferable c)
    {
        System.out.println("We lost ownership on the Clipboard");
    }
   
    public static void main(String args[])
    {
        clipboard c=new clipboard();
        c.resize(new Dimension(300,300));
        c.show();
    }
   
    clipboard()
    {
        setLayout(new BorderLayout(10,10));
        pA.setLayout(new FlowLayout());
        pB.setLayout(new FlowLayout());
        pA.add("West",t1);
        pA.add("East",t2);
       
        b1.addActionListener( new ActionListener() {
           
            public void actionPerformed(ActionEvent e)
            {
                Transfer trans=new Transfer(t1.getSelectedText());
                Clip.setContents(trans,owner);
            }
        });
       
       
        b2.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
               
                Transferable data=Clip.getContents(this);
                String s;
                if (data.isDataFlavorSupported(new DataFlavor("text/insidejava","Test on InsideJava")))
                    System.out.println("Transferable supports text/insidejava Mime Type.");
               
                if (data.isDataFlavorSupported(DataFlavor.stringFlavor))
                    System.out.println("Transferable supports application/x-java-serializedobject Mime Type");
                try {
                   
                    s=(String)data.getTransferData(new DataFlavor("text/insidejava","Test on InsideJava"));
                    t2.setText(s);
                   
                   
                }
                catch (UnsupportedFlavorException ex) {System.out.println("Unsupported Flavor!");}
                catch (IOException ex) {System.out.println("IOException!");}
               
            }
        });
       
        pB.add(b1);
        pB.add(b2);
       
        add("South",pB);
        add("Center",pA);
    }
}

class Transfer implements Transferable
{
    String s;
   
    public Transfer(String s)
    {   
        this.s=s;
    }
   
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
    {
        if (flavor.getMimeType().equals("text/insidejava")) return s;
        if (flavor==DataFlavor.stringFlavor) return s;
        return null;
    }
   
    public boolean isDataFlavorSupported(DataFlavor flavor)
    {
        System.out.println("isDataFlavorSupported Method called with:");
        System.out.println(" Mime Type: "+flavor.getMimeType());
        System.out.println(" Human Name: "+flavor.getHumanPresentableName());
        if (flavor.getMimeType().equals("text/insidejava") ||flavor==DataFlavor.stringFlavor) return true;
        else return false;
    }
   
    public DataFlavor[] getTransferDataFlavors()
    {
        DataFlavor d[]=new DataFlavor[2];
        d[0]=new DataFlavor("text/insidejava","Test on InsideJava");
        d[1]=DataFlavor.stringFlavor;
        return d;
    }
   
}

This page was last updated 06 March 1998