package org.freehep.util.export;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.SystemFlavorMap;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* A Transferable for putting vector graphics onto the system clipboard.
* This is particularly useful on Windows where EMF format can be used to copy
* vector graphics onto the system clipboard, from where it can be pasted into
* many applications, including PowerPoint and Word. VectorGraphicsTranferable
* will fall back to using a bitmap image format if no suitable VectorGraphics
* format is registered.
* <p>
* Note: This only works with JDK 1.4 or later.
* @author tonyj
* @version $Id: VectorGraphicsTransferable.java 8584 2006-08-10 23:06:37Z duns $
*/
public class VectorGraphicsTransferable implements ClipboardOwner, Transferable
{
private Component component;
private DataFlavor imageFlavor = new DataFlavor("image/x-java-image; class=java.awt.Image", "Image");
private Map types = new HashMap();
private static Map defaultTypes;
/**
* Create a VectorGraphicsTransferable with the built-in flavor/ExportFileType associations
* @param c The Component whose graphics will be transfered
*/
public VectorGraphicsTransferable(Component c)
{
this(c,true);
}
/**
* Create a VectorGraphicsTransferable.
* @param c The Component whose graphics will be transfered
* @param addDefaultAssociations Add the standard flavor/ExportFileType associations
*/
public VectorGraphicsTransferable(Component c, boolean addDefaultAssociations)
{
this.component = c;
if (addDefaultAssociations) addDefaultFileTypes();
}
public Object getTransferData(DataFlavor dataFlavor) throws UnsupportedFlavorException, IOException
{
// System.out.println(dataFlavor);
if (dataFlavor.match(imageFlavor))
{
Image img = component.createImage(component.getWidth(),component.getHeight());
Graphics g = img.getGraphics();
component.print(g);
g.dispose();
return img;
}
else
{
ExportFileType type = (ExportFileType) types.get(dataFlavor);
if (type != null)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
type.exportToFile(out,component,component,null,component.getName());
out.close();
return new ByteArrayInputStream(out.toByteArray());
}
}
throw new UnsupportedFlavorException(dataFlavor);
}
public DataFlavor[] getTransferDataFlavors()
{
DataFlavor[] result = new DataFlavor[types.size() + 1];
types.keySet().toArray(result);
result[types.size()] = imageFlavor;
return result;
}
public boolean isDataFlavorSupported(DataFlavor dataFlavor)
{
if (dataFlavor.match(imageFlavor)) return true;
if (types.containsKey(dataFlavor)) return true;
return false;
}
public void lostOwnership(Clipboard clipboard, Transferable transferable)
{
}
/**
* Associate a DataFlavor with the ExportFileType
*/
public void addExportFileType(DataFlavor flavor, ExportFileType type)
{
types.put(flavor,type);
}
private void addDefaultFileTypes()
{
if (defaultTypes == null) defaultTypes = createDefaultTypes();
types.putAll(defaultTypes);
}
private static Map createDefaultTypes()
{
Map result = new HashMap();
// TODO: It would make sense to check for services which implement some
// interface, rather than having this hardwired here.
addType(result, "ENHMETAFILE", "image/emf",
"Enhanced Meta File",
"org.freehep.graphicsio.emf.EMFExportFileType");
// DISABLED for now, MacOS X does not pick up PDF and or PNG
// addType(result, "PDF", "application/pdf",
// "Portable Document Format",
// "org.freehep.graphicsio.pdf.PDFExportFileType");
// addType(result, "PNG", "application/pdf",
// "Portable Network Graphics",
// "org.freehep.graphicsio.png.PNGExportFileType");
return result;
}
private static void addType(Map result, String atom, String mimeType, String description, String className)
{
try
{
DataFlavor df = new DataFlavor(mimeType, description);
SystemFlavorMap map = (SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
map.addUnencodedNativeForFlavor(df, atom);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class cls = loader == null ? Class.forName(className) : loader.loadClass(className);
ExportFileType type = (ExportFileType) cls.newInstance();
result.put(df,type);
}
catch (Throwable x)
{
System.err.println("Unable to install flavor for mime type '"+mimeType+"' (this is expected if not using JDK 1.4)");
}
}
}