Java Vector Cut and Paste Library

This is the home page for the Java Library JVectCutAndPaste. This library provides :

The java cut and paste library probably suffers from the "good enough for me" syndrom. That is, I did not try to support all graphic features (in particular as far as colour transparency and filling are concerned), but only those I needed. If you want more, feel free to contribute code. So limitations are:

Getting the source : the current distribution of the library is part of JSesh. Get the whole sources for JSesh:

hg clone http://jsesh.hg.sourceforge.net:8000/hgroot/jsesh/jsesh

The sources for this particular library are in the folder jvectClipboard.

Note that there are other libraries for vector graphics. If you need more complete capabilities, you might have a look at freeHep. When I started the JSesh project, it didn't provide all functionnalities I needed, hence the creation of this library. Now, I haven't tried it yet, but the current version of FreeHep also provides clipboard capabilities (but it probably only works on Windows).

Trying it

(deprecated. I must provide a maven-compatible system).

Get the source distribution, and type "ant run".

You will see a small window with a "copy" button. Click. Then open your favourite text editor (Word, OpenOffice, Mellel...).

Type "paste", and lo, a nice red rectangle was pasted!

License and the like

This library is distributed under the LGPL (the GNU lesser public license), because I want it to be usable, including in commercial softwares. PDF copy/paste is done using an old version of IText, because of licenses issues (version 2.1.5 was still under the LGPL).

Using the library for creating vector graphics

The various Graphics2D object provided (for WMF, EMF, MACPICT, EPS, SVG...) are relatively easy to use. Please notice that I made them for a specific software, JSesh, which might mean they lack some features you need. In particular, I didn't bother to emulate transparency and the like.

Currently, text is rendered as drawing outlines which means that :

  1. it will render reasonably well
  2. but the graphical file will be large, as the text is rendered as a drawing.

Pasting vector graphics

Introduction

Vector graphics are often difficult to copy on the clipboard. In fact, on Windows, it used to be impossible without using native code, as one had to send the address of the vector graphics.

This is why this system uses a trick (I'm not really sure how I decided to use it. I think a blog about Freemind gave me the idea. However, I haven't seen any free Java software which performed vector cut and paste (and on all platforms).

The trick is that the vector graphic is embedded in RTF. And Java can copy RTF on the clipboard without any problem. That's the good news.

Now, for the bad news:

With recent versions of Java, things have improved, and some formats can be cut and pasted natively. For instance, PDF on Mac OS X, and EMF on Windows.

Simple case

You can have a look at JVectClipboardTest for a simple example.

Basically, using the library is as simple as :

   // creating a SimpleGraphicsObject. The size is expressed in points.
    SimpleClipGraphics clipGraphics = new SimpleClipGraphics(300, 200);
   // get the graphics object. The unit used is 1 unit = 1 point.
   Graphics2D g = clipGraphics.getGraphics();
   // Draw...
   g.setColor(Color.RED);
   g.fill(new Rectangle2D.Double(30, 30, 100, 100));
   // Dispose the graphics object...
   g.dispose();
   // Send it to the clipboard
   clipGraphics.copyToClipboard();

And that's all.

You might want to choose the format used for the embedded vector pictures. This is done by calling setPictureFormat before you call getGraphics. The default format used is MACPICT.

SimpleClipGraphics clipGraphics = new SimpleClipGraphics(300, 200);
clipGraphics.setPictureFormat(PictureFormat.EMF);
Graphics2D g = clipGraphics.getGraphics();

How should you choose the format? Well:

Of course, if you use curves in your drawing, you will get a reasonable approximation with MACPICT and WMF. But the EMF picture will be better.

More complex cases

In more complex cases, you want to propose a number of different formats on the clipboard.

Then, the solution is usually to create your own Transferable class. This class will contain the original data which generates the picture, and propose it in various "flavors".

Your code will be something like :

public class MyTransferable implements Transferable {
   public static final DataFlavor RTF_FLAVOR = new DataFlavor("text/rtf", null);

   private static final DataFlavor[] flavors= {RTF_FLAVOR, DataFlavor.stringFlavor};

        private SomeObject objectToPaste;


  public RTFTransferable(RTFPicture rtfPicture) {
        this.rtfPicture= rtfPicture;
   }

  public Object getTransferData(DataFlavor flavor)
           throws UnsupportedFlavorException, IOException {
       if (RTF_FLAVOR.equals(flavor)) {
                       EMFPicture pict= new EMFPicture(.....); // use the appropriate size for your data....
                       Graphics2D g= pict.getGraphics();
                        // draw on g what you want to draw...
                        ...
                        g.dispose();
          return new ByteArrayInputStream(RTFPictureUtils
                    .createRTFByteArray(pict));
                } else if (DataFlavor.stringFlavor.equals(flavor)) {
                        return objectToPaste.toString();
      } else {
           throw new UnsupportedFlavorException(flavor);
      }
  }

public DataFlavor[] getTransferDataFlavors() {
     return flavors;
    }

public boolean isDataFlavorSupported(DataFlavor flavor) {
      DataFlavor[] flavors = getTransferDataFlavors();
       for (int i = 0; i < flavors.length; i++) {
          if (flavors[i].equals(flavor)) {
               return true;
           }
      }
      return false;
  }
}

Of course, this is simply a technical example. I suggest to isolate the drawing code in another class.

Not using the library

If your target is a Mac, you might consider pasting PDF on the clipboard. PDF works great with most "real" Mac softwares, like Mellel. Word 2008 also support PDF (which is a good move). Now, of course, embedded PDF will be somehow problematic if you want to share your file with someone running windows. You can use IText to produce PDF.

To do this, you need to create a Transferable object which handle the PDF flavour. The DataFlavor to use is: public static final DataFlavor PDFFlavor = new DataFlavor( "application/pdf", null); I might write a longer explanation later, with a short example. If you are interested, you may look at the JSesh code.

A useful utility

If you need to experiment and try to see what java can copy or paste, I have writen for my own tests a small class called TransfertTest

It's stand-alone. Just get and compile. It allows you to inspect the clipboard, and try to copy or paste stuff.