/**
* @version 1.10 1999-09-20
* @author Cay Horstmann
*/
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class MimeClipboardTest {
public static void main(String[] args) {
JFrame frame = new MimeClipboardFrame();
frame.show();
}
}
class MimeClipboardFrame extends JFrame implements ActionListener {
public MimeClipboardFrame() {
setSize(300, 300);
setTitle("MimeClipboardTest");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
label = new JLabel();
contentPane.add(label, "Center");
JMenu fileMenu = new JMenu("File");
openItem = new JMenuItem("Open");
openItem.addActionListener(this);
fileMenu.add(openItem);
exitItem = new JMenuItem("Exit");
exitItem.addActionListener(this);
fileMenu.add(exitItem);
JMenu editMenu = new JMenu("Edit");
copyItem = new JMenuItem("Copy");
copyItem.addActionListener(this);
editMenu.add(copyItem);
pasteItem = new JMenuItem("Paste");
pasteItem.addActionListener(this);
editMenu.add(pasteItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(editMenu);
setJMenuBar(menuBar);
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source == openItem) {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
String name = f.getName().toLowerCase();
return name.endsWith(".gif") || name.endsWith(".jpg")
|| name.endsWith(".jpeg") || f.isDirectory();
}
public String getDescription() {
return "Image files";
}
});
int r = chooser.showOpenDialog(this);
if (r == JFileChooser.APPROVE_OPTION) {
String name = chooser.getSelectedFile().getAbsolutePath();
setImage(Toolkit.getDefaultToolkit().getImage(name));
}
} else if (source == exitItem)
System.exit(0);
else if (source == copyItem)
copy();
else if (source == pasteItem)
paste();
}
private void copy() {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(theImage, 0);
try {
tracker.waitForID(0);
} catch (InterruptedException e) {
}
BufferedImage image = new BufferedImage(theImage.getWidth(null),
theImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.drawImage(theImage, 0, 0, null);
Bitmap bitmap = new Bitmap(image);
SerializableSelection selection = new SerializableSelection(bitmap);
mimeClipboard.setContents(selection, null);
}
private void paste() {
Transferable selection = mimeClipboard.getContents(this);
try {
Bitmap bitmap = (Bitmap) selection
.getTransferData(SerializableSelection.serializableFlavor);
setImage(bitmap.getImage());
} catch (Exception e) {
}
}
public void setImage(Image image) {
theImage = image;
label.setIcon(new ImageIcon(image));
}
private static Clipboard mimeClipboard = new MimeClipboard(Toolkit
.getDefaultToolkit().getSystemClipboard());
private Image theImage;
private JLabel label;
private JMenuItem openItem;
private JMenuItem exitItem;
private JMenuItem copyItem;
private JMenuItem pasteItem;
}
class Bitmap implements Serializable {
public Bitmap(BufferedImage image) {
type = image.getType();
width = image.getWidth();
height = image.getHeight();
WritableRaster raster = image.getRaster();
data = raster.getDataElements(0, 0, width, height, null);
}
public BufferedImage getImage() {
BufferedImage image = new BufferedImage(width, height, type);
WritableRaster raster = image.getRaster();
raster.setDataElements(0, 0, width, height, data);
return image;
}
private int type;
private int width;
private int height;
private Object data;
}
class SerializableSelection implements Transferable {
public SerializableSelection(Serializable object) {
theObject = object;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(serializableFlavor);
}
public synchronized Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException {
if (flavor.equals(serializableFlavor)) {
return theObject;
} else {
throw new UnsupportedFlavorException(flavor);
}
}
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public static final DataFlavor serializableFlavor = new DataFlavor(
java.io.Serializable.class, "Serializable Object");
private static DataFlavor[] flavors = { serializableFlavor };
private Serializable theObject;
}
class MimeClipboard extends Clipboard {
public MimeClipboard(Clipboard cb) {
super("MIME/" + cb.getName());
clip = cb;
}
public synchronized void setContents(Transferable contents,
ClipboardOwner owner) {
if (contents instanceof SerializableSelection) {
try {
DataFlavor flavor = SerializableSelection.serializableFlavor;
Serializable obj = (Serializable) contents
.getTransferData(flavor);
String enc = encode(obj);
String header = "Content-type: " + flavor.getMimeType()
+ "\nContent-length: " + enc.length() + "\n\n";
StringSelection selection = new StringSelection(header + enc);
clip.setContents(selection, owner);
} catch (UnsupportedFlavorException e) {
} catch (IOException e) {
}
} else
clip.setContents(contents, owner);
}
public synchronized Transferable getContents(Object requestor) {
Transferable contents = clip.getContents(requestor);
if (contents instanceof StringSelection) {
String data = null;
try {
data = (String) contents
.getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException e) {
return contents;
} catch (IOException e) {
return contents;
}
if (!data.startsWith("Content-type: "))
return contents;
int start = -1;
// skip three newlines
for (int i = 0; i < 3; i++) {
start = data.indexOf('\n', start + 1);
if (start < 0)
return contents;
}
Serializable obj = decode(data.substring(start));
SerializableSelection selection = new SerializableSelection(obj);
return selection;
} else
return contents;
}
public static String encode(Serializable obj) {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try {
Base64OutputStream b64Out = new Base64OutputStream(bOut);
ObjectOutputStream out = new ObjectOutputStream(b64Out);
out.writeObject(obj);
out.close();
return bOut.toString("8859_1");
} catch (IOException exception) {
return null;
}
}
public static Serializable decode(String s) {
try {
byte[] bytes = s.getBytes("8859_1");
ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
Base64InputStream b64In = new Base64InputStream(bIn);
ObjectInputStream in = new ObjectInputStream(b64In);
Object obj = in.readObject();
in.close();
return (Serializable) obj;
} catch (Exception e) {
return null;
}
}
private Clipboard clip;
}
/*
* BASE64 encoding encodes 3 bytes into 4 characters.
* |11111122|22223333|33444444| Each set of 6 bits is encoded according to the
* toBase64 map. If the number of input bytes is not a multiple of 3, then the
* last group of 4 characters is padded with one or two = signs. Each output
* line is at most 76 characters.
*/
class Base64OutputStream extends FilterOutputStream {
public Base64OutputStream(OutputStream out) {
super(out);
}
public void write(int c) throws IOException {
inbuf[i] = c;
i++;
if (i == 3) {
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4)
| ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[((inbuf[1] & 0x0F) << 2)
| ((inbuf[2] & 0xC0) >> 6)]);
super.write(toBase64[inbuf[2] & 0x3F]);
col += 4;
i = 0;
if (col >= 76) {
super.write('\n');
col = 0;
}
}
}
public void flush() throws IOException {
if (i == 1) {
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[(inbuf[0] & 0x03) << 4]);
super.write('=');
super.write('=');
} else if (i == 2) {
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4)
| ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[(inbuf[1] & 0x0F) << 2]);
super.write('=');
}
i = 0;
}
private static char[] toBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/' };
private int col = 0;
private int i = 0;
private int[] inbuf = new int[3];
}
class Base64InputStream extends FilterInputStream {
public Base64InputStream(InputStream in) {
super(in);
}
public int read(byte[] b, int off, int len) throws IOException {
if (len > b.length - off)
len = b.length - off;
for (int i = 0; i < len; i++) {
int ch = read();
if (ch == -1)
return i;
b[i + off] = (byte) ch;
}
return len;
}
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
public int read() throws IOException {
int r;
if (i == 0) { // skip whitespace
do {
ch[0] = super.read();
if (ch[0] == -1)
return -1;
} while (Character.isWhitespace((char) ch[0]));
ch[1] = super.read();
if (ch[1] == -1)
return -1;
i++;
r = (fromBase64[ch[0]] << 2) | (fromBase64[ch[1]] >> 4);
} else if (i == 1) {
ch[2] = super.read();
if (ch[2] == '=' || ch[2] == -1)
return -1;
i++;
r = ((fromBase64[ch[1]] & 0x0F) << 4) | (fromBase64[ch[2]] >> 2);
} else {
ch[3] = super.read();
if (ch[3] == '=' || ch[3] == -1)
return -1;
i = 0;
r = ((fromBase64[ch[2]] & 0x03) << 6) | fromBase64[ch[3]];
}
return r;
}
private static int[] fromBase64 = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62,
-1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 };
int i = 0;
int[] ch = new int[4];
}
|