| /* Demo.java -- And example of copy/paste datatransfer |
| Copyright (C) 2005 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath examples. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. */ |
| |
| package gnu.classpath.examples.datatransfer; |
| |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.awt.datatransfer.*; |
| |
| import java.io.*; |
| import java.net.URL; |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.Random; |
| |
| /** |
| * An example how datatransfer works for copying and pasting data to |
| * and from other programs. |
| */ |
| class Demo |
| extends Frame |
| implements ActionListener, ItemListener, FlavorListener |
| { |
| public static void main(String args[]) |
| { |
| new Demo(); |
| } |
| |
| private TextArea text; |
| private Button copyText; |
| private Button pasteText; |
| |
| private ImageComponent image; |
| private Button copyImage; |
| private Button pasteImage; |
| |
| private ObjectComponent object; |
| private Button copyObject; |
| private Button pasteObject; |
| |
| private FilesComponent files; |
| private Button copyFiles; |
| private Button pasteFiles; |
| |
| private FlavorsComponent flavors; |
| private FlavorDetailsComponent details; |
| |
| private Demo() |
| { |
| super("GNU Classpath datatransfer"); |
| |
| /* Add all the different panel to the main window in one row. */ |
| setLayout(new GridLayout(5, 1, 10, 10)); |
| add(createTextPanel()); |
| add(createImagePanel()); |
| add(createObjectPanel()); |
| add(createFilesPanel()); |
| add(createFlavorsPanel()); |
| |
| /* Add listeners for the various buttons and events we are |
| interested in. */ |
| addWindowListener(new WindowAdapter () |
| { |
| public void windowClosing (WindowEvent e) |
| { |
| dispose(); |
| } |
| }); |
| flavors.addItemListener(this); |
| Toolkit t = Toolkit.getDefaultToolkit(); |
| Clipboard c = t.getSystemClipboard(); |
| c.addFlavorListener(this); |
| |
| /* Show time! */ |
| pack(); |
| show(); |
| } |
| |
| /** |
| * The Text Panel will show simple text that can be copied and pasted. |
| */ |
| private Panel createTextPanel() |
| { |
| Panel textPanel = new Panel(); |
| textPanel.setLayout(new BorderLayout()); |
| text = new TextArea("GNU Everywhere!", |
| 2, 80, |
| TextArea.SCROLLBARS_VERTICAL_ONLY); |
| text.setEditable(false); |
| text.setEnabled(true); |
| Panel textButtons = new Panel(); |
| textButtons.setLayout(new FlowLayout()); |
| copyText = new Button("Copy text"); |
| copyText.addActionListener(this); |
| pasteText = new Button("Paste text"); |
| pasteText.addActionListener(this); |
| textButtons.add(copyText); |
| textButtons.add(pasteText); |
| textPanel.add(text, BorderLayout.CENTER); |
| textPanel.add(textButtons, BorderLayout.SOUTH); |
| return textPanel; |
| } |
| |
| /** |
| * The Image Panel shows an image that can be copied to another |
| * program or be replaced by pasting in an image from another |
| * application. |
| */ |
| private Panel createImagePanel() |
| { |
| Panel imagePanel = new Panel(); |
| imagePanel.setLayout(new BorderLayout()); |
| URL imageurl = this.getClass() |
| .getResource("/gnu/classpath/examples/icons/big-fullscreen.png"); |
| Image img = Toolkit.getDefaultToolkit().createImage(imageurl); |
| image = new ImageComponent(img); |
| Panel imageButtons = new Panel(); |
| copyImage = new Button("Copy image"); |
| copyImage.addActionListener(this); |
| pasteImage = new Button("Paste image"); |
| pasteImage.addActionListener(this); |
| imageButtons.add(copyImage); |
| imageButtons.add(pasteImage); |
| imagePanel.add(image, BorderLayout.CENTER); |
| imagePanel.add(imageButtons, BorderLayout.SOUTH); |
| return imagePanel; |
| } |
| |
| /** |
| * The Object Panel holds a simple (Point) object that can be copied |
| * and pasted to another program that supports exchanging serialized |
| * objects. |
| */ |
| private Panel createObjectPanel() |
| { |
| Panel objectPanel = new Panel(); |
| objectPanel.setLayout(new BorderLayout()); |
| Random random = new Random(); |
| int x = (byte) random.nextInt(); |
| int y = (byte) random.nextInt(); |
| object = new ObjectComponent(new Point(x, y)); |
| Panel objectButtons = new Panel(); |
| copyObject = new Button("Copy object"); |
| copyObject.addActionListener(this); |
| pasteObject = new Button("Paste object"); |
| pasteObject.addActionListener(this); |
| objectButtons.add(copyObject); |
| objectButtons.add(pasteObject); |
| objectPanel.add(object, BorderLayout.CENTER); |
| objectPanel.add(objectButtons, BorderLayout.SOUTH); |
| return objectPanel; |
| } |
| |
| /** |
| * The Files Panel shows the files from the current working |
| * directory. They can be copied and pasted between other |
| * applications that support the exchange of file lists. |
| */ |
| private Panel createFilesPanel() |
| { |
| Panel filesPanel = new Panel(); |
| filesPanel.setLayout(new BorderLayout()); |
| files = new FilesComponent(new File(".").listFiles()); |
| Panel filesButtons = new Panel(); |
| copyFiles = new Button("Copy files"); |
| copyFiles.addActionListener(this); |
| pasteFiles = new Button("Paste files"); |
| pasteFiles.addActionListener(this); |
| filesButtons.add(copyFiles); |
| filesButtons.add(pasteFiles); |
| filesPanel.add(files, BorderLayout.CENTER); |
| filesPanel.add(filesButtons, BorderLayout.SOUTH); |
| return filesPanel; |
| } |
| |
| /** |
| * The Flavors Panel shows the different formats (mime-types) that |
| * data on the clipboard is available in. By clicking on a flavor |
| * details about the representation class and object is given. |
| */ |
| private Panel createFlavorsPanel() |
| { |
| Panel flavorsPanel = new Panel(); |
| flavorsPanel.setLayout(new BorderLayout()); |
| Label flavorsHeader = new Label("Flavors on clipboard:"); |
| Toolkit t = Toolkit.getDefaultToolkit(); |
| Clipboard c = t.getSystemClipboard(); |
| DataFlavor[] dataflavors = c.getAvailableDataFlavors(); |
| flavors = new FlavorsComponent(dataflavors); |
| details = new FlavorDetailsComponent(null); |
| flavorsPanel.add(flavorsHeader, BorderLayout.NORTH); |
| flavorsPanel.add(flavors, BorderLayout.CENTER); |
| flavorsPanel.add(details, BorderLayout.SOUTH); |
| return flavorsPanel; |
| } |
| |
| /** |
| * FlavorListener implementation that updates the Flavors Panel |
| * whenever a change in the mime-types available has been detected. |
| */ |
| public void flavorsChanged(FlavorEvent event) |
| { |
| Toolkit t = Toolkit.getDefaultToolkit(); |
| Clipboard c = t.getSystemClipboard(); |
| DataFlavor[] dataflavors = c.getAvailableDataFlavors(); |
| flavors.setFlavors(dataflavors); |
| details.setDataFlavor(null); |
| } |
| |
| /** |
| * ItemChangeListener implementation that updates the flavor details |
| * whenever the user selects a different representation of the data |
| * available on the clipboard. |
| */ |
| public void itemStateChanged(ItemEvent evt) |
| { |
| DataFlavor df = null; |
| String s = flavors.getSelectedItem(); |
| if (s != null) |
| { |
| try |
| { |
| df = new DataFlavor(s); |
| } |
| catch (ClassNotFoundException cnfe) |
| { |
| cnfe.printStackTrace(); |
| } |
| } |
| details.setDataFlavor(df); |
| } |
| |
| /** |
| * ActionListener implementations that will copy or past data |
| * to/from the clipboard when the user requests that for the text, |
| * image, object of file component. |
| */ |
| public void actionPerformed (ActionEvent evt) |
| { |
| Button b = (Button) evt.getSource(); |
| Toolkit t = Toolkit.getDefaultToolkit(); |
| Clipboard c = t.getSystemClipboard(); |
| if (b == copyText) |
| c.setContents(new StringSelection(text.getText()), null); |
| |
| if (b == pasteText) |
| { |
| String s = null; |
| try |
| { |
| s = (String) c.getData(DataFlavor.stringFlavor); |
| } |
| catch (UnsupportedFlavorException dfnse) |
| { |
| } |
| catch (IOException ioe) |
| { |
| } |
| catch (ClassCastException cce) |
| { |
| } |
| if (s == null) |
| t.beep(); |
| else |
| text.setText(s); |
| } |
| |
| if (b == copyImage) |
| c.setContents(new ImageSelection(image.getImage()), null); |
| |
| if (b == pasteImage) |
| { |
| Image i = null; |
| try |
| { |
| i = (Image) c.getData(DataFlavor.imageFlavor); |
| } |
| catch (UnsupportedFlavorException dfnse) |
| { |
| } |
| catch (IOException ioe) |
| { |
| } |
| catch (ClassCastException cce) |
| { |
| } |
| if (i == null) |
| t.beep(); |
| else |
| image.setImage(i); |
| } |
| |
| if (b == copyObject) |
| c.setContents(new ObjectSelection(object.getObject()), null); |
| |
| if (b == pasteObject) |
| { |
| Serializable o = null; |
| try |
| { |
| o = (Serializable) c.getData(ObjectSelection.objFlavor); |
| } |
| catch (UnsupportedFlavorException dfnse) |
| { |
| } |
| catch (IOException ioe) |
| { |
| } |
| catch (ClassCastException cce) |
| { |
| } |
| if (o == null) |
| t.beep(); |
| else |
| object.setObject(o); |
| } |
| |
| if (b == copyFiles) |
| c.setContents(new FilesSelection(files.getFiles()), null); |
| |
| if (b == pasteFiles) |
| { |
| java.util.List fs = null; |
| try |
| { |
| fs = (java.util.List) c.getData(DataFlavor.javaFileListFlavor); |
| } |
| catch (UnsupportedFlavorException dfnse) |
| { |
| } |
| catch (IOException ioe) |
| { |
| } |
| catch (ClassCastException cce) |
| { |
| } |
| if (fs == null) |
| t.beep(); |
| else |
| files.setFiles(fs); |
| } |
| } |
| |
| /** |
| * Simple awt component that shows an settable image. |
| */ |
| static class ImageComponent extends Component |
| { |
| private Image image; |
| |
| ImageComponent(Image image) |
| { |
| setSize(20, 20); |
| setImage(image); |
| } |
| |
| Image getImage() |
| { |
| return image; |
| } |
| |
| void setImage(Image image) |
| { |
| this.image = image; |
| repaint(); |
| } |
| |
| public void paint(Graphics g) |
| { |
| g.drawImage(image, 0, 0, getWidth(), getHeight(), this); |
| } |
| } |
| |
| /** |
| * Simple awt component that shows a settable Serializable object. |
| */ |
| static class ObjectComponent extends TextArea |
| { |
| private Serializable object; |
| |
| ObjectComponent(Serializable object) |
| { |
| super("", 2, 80, TextArea.SCROLLBARS_NONE); |
| setEditable(false); |
| setEnabled(false); |
| setObject(object); |
| } |
| |
| Serializable getObject() |
| { |
| return object; |
| } |
| |
| void setObject(Serializable object) |
| { |
| this.object = object; |
| setText("Class: " + object.getClass().getName() |
| + "\n" |
| + "toString(): " + object.toString()); |
| repaint(); |
| } |
| } |
| |
| /** |
| * Simple awt component that shows a settable list of Files. |
| */ |
| static class FilesComponent extends List |
| { |
| private File[] files; |
| |
| FilesComponent(File[] files) |
| { |
| super(4, true); |
| setFiles(files); |
| } |
| |
| File[] getFiles() |
| { |
| String[] strings = getSelectedItems(); |
| if (strings == null || strings.length == 0) |
| return (File[]) files.clone(); |
| |
| File[] fs = new File[strings.length]; |
| for (int i = 0; i < strings.length; i++) |
| fs[i] = new File(strings[i]); |
| return fs; |
| } |
| |
| void setFiles(File[] files) |
| { |
| this.files = files; |
| removeAll(); |
| for (int i = 0; i < files.length; i++) |
| { |
| addItem(files[i].toString()); |
| select(i); |
| } |
| } |
| |
| void setFiles(java.util.List list) |
| { |
| File[] fs = new File[list.size()]; |
| int i = 0; |
| Iterator it = list.iterator(); |
| while (it.hasNext()) |
| fs[i++] = (File) it.next(); |
| |
| setFiles(fs); |
| } |
| } |
| |
| /** |
| * Simple awt component that shows a settable list of DataFlavors. |
| */ |
| static class FlavorsComponent extends List |
| { |
| FlavorsComponent(DataFlavor[] flavors) |
| { |
| super(4); |
| setFlavors(flavors); |
| } |
| |
| void setFlavors(DataFlavor[] flavors) |
| { |
| removeAll(); |
| for (int i = 0; i < flavors.length; i++) |
| { |
| addItem(flavors[i].getMimeType()); |
| } |
| } |
| } |
| |
| /** |
| * Simple awt component that shows the details for and an object as |
| * found on the system clipboard as represented by a given |
| * DataFlavor. |
| */ |
| static class FlavorDetailsComponent extends TextArea |
| { |
| private DataFlavor df; |
| |
| FlavorDetailsComponent(DataFlavor df) |
| { |
| super("", 2, 80, TextArea.SCROLLBARS_NONE); |
| setEditable(false); |
| setEnabled(false); |
| setDataFlavor(df); |
| } |
| |
| void setDataFlavor(DataFlavor df) |
| { |
| if (df == this.df |
| || (df != null && df.equals(this.df))) |
| return; |
| |
| this.df = df; |
| |
| if (df == null) |
| setText("No flavor selected"); |
| else |
| { |
| Object o = null; |
| Throwable exception = null; |
| try |
| { |
| Toolkit t = Toolkit.getDefaultToolkit(); |
| Clipboard c = t.getSystemClipboard(); |
| o = c.getData(df); |
| } |
| catch (Throwable t) |
| { |
| exception = t; |
| } |
| if (o != null) |
| { |
| setText("Data: " + o.getClass().getName() |
| + "\n" |
| + o); |
| } |
| else |
| { |
| setText("Error retrieving: " + df |
| + "\n" |
| + exception != null ? exception.toString() : ""); |
| } |
| } |
| repaint(); |
| } |
| } |
| |
| /** |
| * Helper class to put an Image on a clipboard as |
| * DataFlavor.imageFlavor. |
| */ |
| static class ImageSelection implements Transferable |
| { |
| private final Image img; |
| |
| ImageSelection(Image img) |
| { |
| this.img = img; |
| } |
| |
| static DataFlavor[] flavors = new DataFlavor[] { DataFlavor.imageFlavor }; |
| public DataFlavor[] getTransferDataFlavors() |
| { |
| return (DataFlavor[]) flavors.clone(); |
| } |
| |
| public boolean isDataFlavorSupported(DataFlavor flavor) |
| { |
| return flavor.equals(DataFlavor.imageFlavor); |
| } |
| |
| public Object getTransferData(DataFlavor flavor) |
| throws UnsupportedFlavorException |
| { |
| if (!isDataFlavorSupported(flavor)) |
| throw new UnsupportedFlavorException(flavor); |
| |
| return img; |
| } |
| } |
| |
| /** |
| * Helper class to put an Object on a clipboard as Serializable |
| * object. |
| */ |
| static class ObjectSelection implements Transferable |
| { |
| private final Serializable obj; |
| |
| ObjectSelection(Serializable obj) |
| { |
| this.obj = obj; |
| } |
| |
| static DataFlavor objFlavor = new DataFlavor(Serializable.class, |
| "Serialized Object"); |
| static DataFlavor[] flavors = new DataFlavor[] { objFlavor }; |
| public DataFlavor[] getTransferDataFlavors() |
| { |
| return (DataFlavor[]) flavors.clone(); |
| } |
| |
| public boolean isDataFlavorSupported(DataFlavor flavor) |
| { |
| return flavor.equals(objFlavor); |
| } |
| |
| public Object getTransferData(DataFlavor flavor) |
| throws UnsupportedFlavorException |
| { |
| if (!isDataFlavorSupported(flavor)) |
| throw new UnsupportedFlavorException(flavor); |
| |
| return obj; |
| } |
| } |
| |
| /** |
| * Helper class to put a List of Files on the clipboard as |
| * DataFlavor.javaFileListFlavor. |
| */ |
| static class FilesSelection implements Transferable |
| { |
| private final File[] files; |
| |
| FilesSelection(File[] files) |
| { |
| this.files = files; |
| } |
| |
| static DataFlavor[] flavors = new DataFlavor[] |
| { DataFlavor.javaFileListFlavor }; |
| public DataFlavor[] getTransferDataFlavors() |
| { |
| return (DataFlavor[]) flavors.clone(); |
| } |
| |
| public boolean isDataFlavorSupported(DataFlavor flavor) |
| { |
| return flavor.equals(DataFlavor.javaFileListFlavor); |
| } |
| |
| public Object getTransferData(DataFlavor flavor) |
| throws UnsupportedFlavorException |
| { |
| if (!isDataFlavorSupported(flavor)) |
| throw new UnsupportedFlavorException(flavor); |
| |
| return Arrays.asList(files); |
| } |
| } |
| } |