|
One of the most useful and convenient user interface mechanisms of graphical user interface environments (such as Windows and the X Window System) is cut and paste. You select some data in one program and cut or copy them to the clipboard. Then, you select another program and paste the clipboard contents into that application. Using the clipboard, you can transfer text, images, or other data from one document to another, or, of course, from one place in a document to another place in the same document. Cut and paste is so natural that most computer users never think about it. However, JDK 1.0 did not support cut and paste. JDK 1.1 implemented a rudimentary clipboard mechanism. That mechanism has been gradually improved and is now quite usable on a number of platforms. Even though the clipboard is conceptually simple, implementing clipboard services is actually harder than you might think. Suppose you copy text from a word processor to the clipboard. If you paste that text into another word processor, then you expect that the fonts and formatting will stay intact. That is, the text in the clipboard needs to retain the formatting information. But if you paste the text into a plain text field, then you expect that just the characters are pasted in, without additional formatting codes. To support this flexibility, the data provider can offer the clipboard data in multiple formats, and the data consumer can pick one of them. The system clipboard implementations of Microsoft Windows and the Macintosh are similar, but, of course, there are slight differences. However, the X Window System clipboard mechanism is much more limitedcutting and pasting of anything but plain text is only sporadically supported. You should consider these limitations when trying out the programs in this section. NOTE
Often, programs need to support cut and paste of data types that the system clipboard cannot handle. The data transfer API supports the transfer of arbitrary local object references in the same virtual machine. Between different virtual machines, you can transfer serialized objects and references to remote objects. Table 7-5 summarizes the data transfer capabilities of the clipboard mechanism.
Classes and Interfaces for Data TransferData transfer in the Java technology is implemented in a package called java.awt.datatransfer. Here is an overview of the most important classes and interfaces of that package.
Transferring TextThe best way to get comfortable with the data transfer classes is to start with the simplest situation: transferring text to and from the system clipboard. The idea of the following program is simple. First, get a reference to the system clipboard. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); For strings to be transferred to the clipboard, they must be wrapped into StringSelection objects. The constructor takes the text you want to transfer. String text = . . . StringSelection selection = new StringSelection(text); The actual transfer is done by a call to setContents, which takes a StringSelection object and a ClipBoardOwner as parameters. If you are not interested in designating a clipboard owner, set the second parameter to null. clipboard.setContents(selection, null); Starting with JDK 5.0, you can bypass the transferable and query the clipboard directly. Let us look at the reverse operation, reading a string from the clipboard. Starting with JDK 5.0, this is quite simple: DataFlavor flavor = DataFlavor.stringFlavor; if (clipboard.isDataFlavorAvailable(flavor) String text = (String) clipboard.getData(flavor); Before JDK 5.0, you had to retrieve the transferable and query it for the available flavors: Transferable contents = clipBoard.getContents(null); if (contents != null && contents.isDataFlavorSupported(flavor)) String text = (String) contents.getTransferData(flavor); According to the API documentation, the parameter of the getContents call is an Object reference of the requesting object. It is not clear why the clipboard collects this information. The return value of getContents may be null. That indicates that the clipboard is either empty or that it has no data that the Java platform knows how to retrieve. Example 7-16 is a program that demonstrates cutting and pasting between a Java application and the system clipboard. Figure 7-45 shows a screen shot. If you select an area of text in the text area and click Copy, then the selected text is copied to the system clipboard. As Figure 7-46 shows, the copied text is indeed stored on the system clipboard. (Run the program c:\windows\system32\clipbrd to display the clipboard viewer in Windows.) When you subsequently click the Paste button, the contents of the clipboard (which may come from a native program) are pasted at the cursor position. Example 7-16. TextTransferTest.java1. import java.awt.*; 2. import java.awt.datatransfer.*; 3. import java.awt.event.*; 4. import java.io.*; 5. import javax.swing.*; 6. 7. /** 8. This program demonstrates the transfer of text 9. between a Java application and the system clipboard. 10. */ 11. public class TextTransferTest 12. { 13. public static void main(String[] args) 14. { 15. JFrame frame = new TextTransferFrame(); 16. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17. frame.setVisible(true); 18. } 19. } 20. 21. /** 22. This frame has a text area and buttons for copying and 23. pasting text. 24. */ 25. class TextTransferFrame extends JFrame 26. { 27. public TextTransferFrame() 28. { 29. setTitle("TextTransferTest"); 30. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 31. 32. textArea = new JTextArea(); 33. add(new JScrollPane(textArea), BorderLayout.CENTER); 34. JPanel panel = new JPanel(); 35. 36. JButton copyButton = new JButton("Copy"); 37. panel.add(copyButton); 38. copyButton.addActionListener(new 39. ActionListener() 40. { 41. public void actionPerformed(ActionEvent event) 42. { 43. copy(); 44. } 45. }); 46. 47. JButton pasteButton = new JButton("Paste"); 48. panel.add(pasteButton); 49. pasteButton.addActionListener(new 50. ActionListener() 51. { 52. public void actionPerformed(ActionEvent event) 53. { 54. paste(); 55. } 56. }); 57. 58. add(panel, BorderLayout.SOUTH); 59. } 60. 61. /** 62. Copies the selected text to the system clipboard. 63. */ 64. private void copy() 65. { 66. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 67. String text = textArea.getSelectedText(); 68. if (text == null) text = textArea.getText(); 69. StringSelection selection = new StringSelection(text); 70. clipboard.setContents(selection, null); 71. } 72. 73. /** 74. Pastes the text from the system clipboard into the 75. text area. 76. */ 77. private void paste() 78. { 79. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 80. DataFlavor flavor = DataFlavor.stringFlavor; 81. if (clipboard.isDataFlavorAvailable(flavor)) 82. { 83. try 84. { 85. String text = (String) clipboard.getData(flavor); 86. textArea.replaceSelection(text); 87. } 88. catch (UnsupportedFlavorException e) 89. { 90. JOptionPane.showMessageDialog(this, e); 91. } 92. catch (IOException e) 93. { 94. JOptionPane.showMessageDialog(this, e); 95. } 96. } 97. } 98. 99. private JTextArea textArea; 100. 101. private static final int DEFAULT_WIDTH = 300; 102. private static final int DEFAULT_HEIGHT = 300; 103. } Figure 7-45. The TextTransferTest programFigure 7-46. The Windows clipboard viewer after a copy java.awt.Toolkit 1.0
java.awt.datatransfer.Clipboard 1.1
java.awt.datatransfer.ClipboardOwner 1.1
java.awt.datatransfer.Transferable 1.1
The Transferable Interface and Data FlavorsAs of JDK 5.0, you can ask the clipboard to list all available flavors: DataFlavor[] flavors = clipboard.getAvailableDataFlavors() In older versions of the JDK, you first got the clipboard contentsan object that implements the transferable interfaceand queried it for the available flavors: Transferable contents = clipBoard.getContents(null); if (contents != null) flavors = transferable.getTransferDataFlavors(); You can also install a FlavorListener onto the clipboard. The listener is notified when the collection of data flavors on the clipboard changes. See the API notes for details. A DataFlavor is defined by two characteristics:
In addition, every data flavor has a human-readable name (such as "GIF Image"). The representation class can be specified with a class parameter in the MIME type, for example, image/gif;class=java.awt.Image NOTE
If no class parameter is given, then the representation class is InputStream. For transferring local, serialized, and remote Java objects, Sun Microsystems defines three MIME types: application/x-java-jvm-local-objectref application/x-java-serialized-object application/x-java-remote-object NOTE
For example, the standard stringFlavor data flavor is described by the MIME type application/x-java-serialized-object;class=java.lang.String java.awt.datatransfer.DataFlavor 1.1
java.awt.datatransfer.Clipboard 1.1
java.awt.datatransfer.Transferable 1.1
java.awt.datatransfer.FlavorListener 5.0
Building an Image TransferableObjects that you want to transfer via the clipboard must implement the transferable interface. The StringSelection class is currently the only public class in the Java standard library that implements the transferable interface. In this section, you will see how to transfer images into the clipboard. Because the JDK does not supply a class for image transfer, you must implement it yourself. The class is completely trivial. It simply reports that the only available data format is DataFlavor.imageFlavor, and it holds an image object. class ImageSelection implements Transferable { public ImageSelection(Image image) { theImage = image; } public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.imageFlavor }; } public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(DataFlavor.imageFlavor); } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { if(flavor.equals(DataFlavor.imageFlavor)) { return theImage; } else { throw new UnsupportedFlavorException(flavor); } } private Image theImage; } NOTE
The program of Example 7-17 demonstrates the transfer of images between a Java application and the system clipboard. When the program starts, it generates a Mandelbrot image. Click the Copy button to copy the image to the clipboard and then paste it into another application. (See Figure 7-47.) From another application, copy an image into the system clipboard. Then click the Paste button and see the image being pasted into the example program. (See Figure 7-48.) Figure 7-47. Copying from a Java program to a native programFigure 7-48. Copying from a native program to a Java programThe program is a straightforward modification of the text transfer program. The data flavor is now DataFlavor.imageFlavor, and we use the ImageSelection class to transfer an image to the system clipboard. Example 7-17. ImageTransferTest.java[View full width] 1. import java.io.*; 2. import java.awt.*; 3. import java.awt.datatransfer.*; 4. import java.awt.event.*; 5. import java.awt.image.*; 6. import javax.swing.*; 7. 8. /** 9. This program demonstrates the transfer of images between a Java application 10. and the system clipboard. 11. */ 12. public class ImageTransferTest 13. { 14. public static void main(String[] args) 15. { 16. JFrame frame = new ImageTransferFrame(); 17. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18. frame.setVisible(true); 19. } 20. } 21. 22. /** 23. This frame has an image label and buttons for copying and pasting an image. 24. */ 25. class ImageTransferFrame extends JFrame 26. { 27. public ImageTransferFrame() 28. { 29. setTitle("ImageTransferTest"); 30. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 31. 32. label = new JLabel(); 33. image = makeMandelbrot(DEFAULT_WIDTH, DEFAULT_HEIGHT); 34. label.setIcon(new ImageIcon(image)); 35. add(new JScrollPane(label), BorderLayout.CENTER); 36. JPanel panel = new JPanel(); 37. 38. JButton copyButton = new JButton("Copy"); 39. panel.add(copyButton); 40. copyButton.addActionListener(new 41. ActionListener() 42. { 43. public void actionPerformed(ActionEvent event) { copy(); } 44. }); 45. 46. JButton pasteButton = new JButton("Paste"); 47. panel.add(pasteButton); 48. pasteButton.addActionListener(new 49. ActionListener() 50. { 51. public void actionPerformed(ActionEvent event) { paste(); } 52. }); 53. 54. add(panel, BorderLayout.SOUTH); 55. } 56. 57. /** 58. Copies the current image to the system clipboard. 59. */ 60. private void copy() 61. { 62. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 63. ImageSelection selection = new ImageSelection(image); 64. clipboard.setContents(selection, null); 65. } 66. 67. /** 68. Pastes the image from the system clipboard into the 69. image label. 70. */ 71. private void paste() 72. { 73. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 74. DataFlavor flavor = DataFlavor.imageFlavor; 75. if (clipboard.isDataFlavorAvailable(flavor)) 76. { 77. try 78. { 79. image = (Image) clipboard.getData(flavor); 80. label.setIcon(new ImageIcon(image)); 81. } 82. catch (UnsupportedFlavorException exception) 83. { 84. JOptionPane.showMessageDialog(this, exception); 85. } 86. catch (IOException exception) 87. { 88. JOptionPane.showMessageDialog(this, exception); 89. } 90. } 91. } 92. 93. /** 94. Makes the Mandelbrot image. 95. @param width the width 96. @parah height the height 97. @return the image 98. */ 99. public BufferedImage makeMandelbrot(int width, int height) 100. { 101. BufferedImage image = new BufferedImage(width, height, BufferedImage .TYPE_INT_ARGB); 102. WritableRaster raster = image.getRaster(); 103. ColorModel model = image.getColorModel(); 104. 105. Color fractalColor = Color.red; 106. int argb = fractalColor.getRGB(); 107. Object colorData = model.getDataElements(argb, null); 108. 109. for (int i = 0; i < width; i++) 110. for (int j = 0; j < height; j++) 111. { 112. double a = XMIN + i * (XMAX - XMIN) / width; 113. double b = YMIN + j * (YMAX - YMIN) / height; 114. if (!escapesToInfinity(a, b)) 115. raster.setDataElements(i, j, colorData); 116. } 117. return image; 118. } 119. 120. private boolean escapesToInfinity(double a, double b) 121. { 122. double x = 0.0; 123. double y = 0.0; 124. int iterations = 0; 125. do 126. { 127. double xnew = x * x - y * y + a; 128. double ynew = 2 * x * y + b; 129. x = xnew; 130. y = ynew; 131. iterations++; 132. if (iterations == MAX_ITERATIONS) return false; 133. } 134. while (x <= 2 && y <= 2); 135. return true; 136. } 137. 138. private JLabel label; 139. private Image image; 140. 141. private static final double XMIN = -2; 142. private static final double XMAX = 2; 143. private static final double YMIN = -2; 144. private static final double YMAX = 2; 145. private static final int MAX_ITERATIONS = 16; 146. 147. private static final int DEFAULT_WIDTH = 300; 148. private static final int DEFAULT_HEIGHT = 300; 149. } 150. 151. /** 152. This class is a wrapper for the data transfer of image 153. objects. 154. */ 155. class ImageSelection implements Transferable 156. { 157. /** 158. Constructs the selection. 159. @param image an image 160. */ 161. public ImageSelection(Image image) 162. { 163. theImage = image; 164. } 165. 166. public DataFlavor[] getTransferDataFlavors() 167. { 168. return new DataFlavor[] { DataFlavor.imageFlavor }; 169. } 170. 171. public boolean isDataFlavorSupported(DataFlavor flavor) 172. { 173. return flavor.equals(DataFlavor.imageFlavor); 174. } 175. 176. public Object getTransferData(DataFlavor flavor) 177. throws UnsupportedFlavorException 178. { 179. if(flavor.equals(DataFlavor.imageFlavor)) 180. { 181. return theImage; 182. } 183. else 184. { 185. throw new UnsupportedFlavorException(flavor); 186. } 187. } 188. 189. private Image theImage; 190. } Using a Local Clipboard to Transfer Object ReferencesSuppose you want to copy and paste a data type that isn't one of the data types supported by the system clipboard. For example, in a drawing program, you may want to allow your users to copy and paste arbitrary shapes. The program in Example 7-18 demonstrates this capability. As you can see in Figure 7-49, the program displays two panels. By moving the rectangle "grabbers" in the left panel, you can change the shape of a cubic curve. The panel on the right side can display an arbitrary shape. Figure 7-49. Transferring local objectsWhen you click the Copy button, the current cubic curve shape is copied. Click Paste, and the Shape object on the clipboard is displayed in the panel on the right-hand side. You can see that the shape is held on a clipboard by the actions of copying a curve and then modifying the curve before pasting. The copied shape, and not the current shape of the curve, is pasted into the right-side panel. To transfer an arbitrary Java object reference within the same JVM, you use the MIME type
However, the JDK doesn't include a transferable wrapper for this type. You can find the code for the wrapper in the example program. It is entirely analogous to the ImageSelection wrapper of the preceding section. An object reference is only meaningful within a single virtual machine. For that reason, you cannot copy the shape object to the system clipboard. Instead, this program uses a local clipboard: Clipboard clipboard = new Clipboard("local"); The construction parameter is the clipboard name. However, using a local clipboard has one major disadvantage. You need to synchronize the local and the system clipboard, so that users don't confuse the two. Currently, the Java platform doesn't do that synchronization for you. Example 7-18. LocalTransferTest.java[View full width] 1. import java.awt.*; 2. import java.awt.datatransfer.*; 3. import java.awt.event.*; 4. import java.awt.geom.*; 5. import java.io.*; 6. import java.util.*; 7. import javax.swing.*; 8. 9. /** 10. This program demonstrates the transfer of object references within the same virtual machine. 11. */ 12. public class LocalTransferTest 13. { 14. public static void main(String[] args) 15. { 16. JFrame frame = new LocalTransferFrame(); 17. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18. frame.setVisible(true); 19. } 20. } 21. 22. /** 23. This frame contains a panel to edit a cubic curve, a 24. panel that can display an arbitrary shape, and copy and 25. paste buttons. 26. */ 27. class LocalTransferFrame extends JFrame 28. { 29. public LocalTransferFrame() 30. { 31. setTitle("LocalTransferTest"); 32. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 33. 34. curvePanel = new CubicCurvePanel(); 35. curvePanel.setPreferredSize(new Dimension(DEFAULT_WIDTH / 2, DEFAULT_HEIGHT)); 36. shapePanel = new ShapePanel(); 37. 38. add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, curvePanel, shapePanel), 39. BorderLayout.CENTER); 40. JPanel panel = new JPanel(); 41. 42. JButton copyButton = new JButton("Copy"); 43. panel.add(copyButton); 44. copyButton.addActionListener(new 45. ActionListener() 46. { 47. public void actionPerformed(ActionEvent event) 48. { 49. copy(); 50. } 51. }); 52. 53. JButton pasteButton = new JButton("Paste"); 54. panel.add(pasteButton); 55. pasteButton.addActionListener(new 56. ActionListener() 57. { 58. public void actionPerformed(ActionEvent event) 59. { 60. paste(); 61. } 62. }); 63. 64. add(panel, BorderLayout.SOUTH); 65. } 66. 67. /** 68. Copies the current cubic curve to the local clipboard. 69. */ 70. private void copy() 71. { 72. LocalSelection selection = new LocalSelection(curvePanel.getShape()); 73. clipboard.setContents(selection, null); 74. } 75. 76. /** 77. Pastes the shape from the local clipboard into the 78. shape panel. 79. */ 80. private void paste() 81. { 82. try 83. { 84. DataFlavor flavor 85. = new DataFlavor("application/x-java-jvm-local-objectref;class=java.awt .Shape"); 86. if (clipboard.isDataFlavorAvailable(flavor)) 87. shapePanel.setShape((Shape) clipboard.getData(flavor)); 88. } 89. catch (ClassNotFoundException e) 90. { 91. JOptionPane.showMessageDialog(this, e); 92. } 93. catch (UnsupportedFlavorException e) 94. { 95. JOptionPane.showMessageDialog(this, e); 96. } 97. catch (IOException e) 98. { 99. JOptionPane.showMessageDialog(this, e); 100. } 101. } 102. 103. private CubicCurvePanel curvePanel; 104. private ShapePanel shapePanel; 105. private Clipboard clipboard = new Clipboard("local"); 106. 107. private static final int DEFAULT_WIDTH = 300; 108. private static final int DEFAULT_HEIGHT = 300; 109. } 110. 111. 112. /** 113. This panel draws a shape and allows the user to 114. move the points that define it. 115. */ 116. class CubicCurvePanel extends JPanel 117. { 118. public CubicCurvePanel() 119. { 120. addMouseListener(new 121. MouseAdapter() 122. { 123. public void mousePressed(MouseEvent event) 124. { 125. for (int i = 0; i < p.length; i++) 126. { 127. double x = p[i].getX() - SIZE / 2; 128. double y = p[i].getY() - SIZE / 2; 129. Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE); 130. if (r.contains(event.getPoint())) 131. { 132. current = i; 133. return; 134. } 135. } 136. } 137. 138. public void mouseReleased(MouseEvent event) 139. { 140. current = -1; 141. } 142. }); 143. 144. addMouseMotionListener(new 145. MouseMotionAdapter() 146. { 147. public void mouseDragged(MouseEvent event) 148. { 149. if (current == -1) return; 150. p[current] = event.getPoint(); 151. repaint(); 152. } 153. }); 154. 155. current = -1; 156. } 157. 158. public void paintComponent(Graphics g) 159. { 160. super.paintComponent(g); 161. Graphics2D g2 = (Graphics2D)g; 162. for (int i = 0; i < p.length; i++) 163. { 164. double x = p[i].getX() - SIZE / 2; 165. double y = p[i].getY() - SIZE / 2; 166. g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE)); 167. } 168. 169. g2.draw(getShape()); 170. } 171. 172. /** 173. Gets the current cubic curve. 174. @return the curve shape 175. */ 176. public Shape getShape() 177. { 178. return new CubicCurve2D.Double(p[0].getX(), p[0].getY(), p[1].getX(), p[1].getY(), 179. p[2].getX(), p[2].getY(), p[3].getX(), p[3].getY()); 180. } 181. 182. private Point2D[] p = 183. { 184. new Point2D.Double(10, 10), 185. new Point2D.Double(10, 100), 186. new Point2D.Double(100, 10), 187. new Point2D.Double(100, 200) 188. }; 189. private static int SIZE = 10; 190. private int current; 191. } 192. 193. /** 194. This panel displays an arbitrary shape. 195. */ 196. class ShapePanel extends JPanel 197. { 198. /** 199. Set the shape to be displayed in this panel. 200. @param aShape any shape 201. */ 202. public void setShape(Shape aShape) 203. { 204. shape = aShape; 205. repaint(); 206. } 207. 208. public void paintComponent(Graphics g) 209. { 210. super.paintComponent(g); 211. Graphics2D g2 = (Graphics2D) g; 212. if (shape != null) g2.draw(shape); 213. } 214. 215. private Shape shape; 216. } 217. 218. /** 219. This class is a wrapper for the data transfer of 220. object references that are transferred within the same 221. virtual machine. 222. */ 223. class LocalSelection implements Transferable 224. { 225. /** 226. Constructs the selection. 227. @param o any object 228. */ 229. LocalSelection(Object o) 230. { 231. obj = o; 232. } 233. 234. public DataFlavor[] getTransferDataFlavors() 235. { 236. DataFlavor[] flavors = new DataFlavor[1]; 237. Class type = obj.getClass(); 238. String mimeType = "application/x-java-jvm-local-objectref;application".equals(flavor.getPrimaryType()) 253. && "x-java-jvm-local-objectref".equals(flavor.getSubType()) 254. && flavor.getRepresentationClass().isAssignableFrom(obj.getClass()); 255. } 256. 257. public Object getTransferData(DataFlavor flavor) 258. throws UnsupportedFlavorException 259. { 260. if (! isDataFlavorSupported(flavor)) 261. throw new UnsupportedFlavorException(flavor); 262. 263. return obj; 264. } 265. 266. private Object obj; 267. } java.awt.datatransfer.Clipboard 1.1
Transferring Java Objects via the System ClipboardSuppose you want to copy and paste objects from one Java application to another. In that case, you cannot use local clipboards. Fortunately, you can place serialized Java objects onto the system clipboard. The program in Example 7-19 demonstrates this capability. The program shows a color chooser. The Copy button copies the current color to the system clipboard as a serialized Color object. The Paste button checks whether the system clipboard contains a serialized Color object. If so, it fetches the color and sets it as the current choice of the color chooser. You can transfer the serialized object between two Java applications (see Figure 7-50). Run two copies of the SerialTransferTest program. Click Copy in the first program, then click Paste in the second program. The Color object is transferred from one virtual machine to the other. Figure 7-50. Data are copied between two instances of a Java applicationTo enable the data transfer, the Java platform places binary data on the system clipboard that contains the serialized object. Another Java programnot necessarily of the same type as the one that generated the clipboard datacan retrieve the clipboard data and deserialize the object. Of course, a non-Java application will not know what to do with the clipboard data. For that reason, the example program offers the clipboard data in a second flavor, as text. The text is simply the result of the toString method, applied to the transferred object. To see the second flavor, run the program, click on a color, and then select the Paste command in your text editor. A string such as java.awt.Color[r=255,g=51,b=51] will be inserted into your document. Essentially no additional programming is required to transfer a serializable object. You use the MIME type
As before, you have to build your own transfer wrappersee the example code for details. Example 7-19. SerialTransferTest.java[View full width] 1. import java.io.*; 2. import java.awt.*; 3. import java.awt.datatransfer.*; 4. import java.awt.event.*; 5. import java.awt.image.*; 6. import javax.swing.*; 7. 8. /** 9. This program demonstrates the transfer of serialized objects between virtual machines. 10. */ 11. public class SerialTransferTest 12. { 13. public static void main(String[] args) 14. { 15. JFrame frame = new SerialTransferFrame(); 16. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17. frame.setVisible(true); 18. } 19. } 20. 21. /** 22. This frame contains a color chooser, and copy and paste buttons. 23. */ 24. class SerialTransferFrame extends JFrame 25. { 26. public SerialTransferFrame() 27. { 28. setTitle("SerialTransferTest"); 29. 30. chooser = new JColorChooser(); 31. add(chooser, BorderLayout.CENTER); 32. JPanel panel = new JPanel(); 33. 34. JButton copyButton = new JButton("Copy"); 35. panel.add(copyButton); 36. copyButton.addActionListener(new 37. ActionListener() 38. { 39. public void actionPerformed(ActionEvent event) 40. { 41. copy(); 42. } 43. }); 44. 45. JButton pasteButton = new JButton("Paste"); 46. panel.add(pasteButton); 47. pasteButton.addActionListener(new 48. ActionListener() 49. { 50. public void actionPerformed(ActionEvent event) 51. { 52. paste(); 53. } 54. }); 55. 56. add(panel, BorderLayout.SOUTH); 57. pack(); 58. } 59. 60. /** 61. Copies the chooser's color into the system clipboard. 62. */ 63. private void copy() 64. { 65. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 66. Color color = chooser.getColor(); 67. SerialSelection selection = new SerialSelection(color); 68. clipboard.setContents(selection, null); 69. } 70. 71. /** 72. Pastes the color from the system clipboard into the chooser. 73. */ 74. private void paste() 75. { 76. Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 77. try 78. { 79. DataFlavor flavor 80. = new DataFlavor("application/x-java-serialized-object;class=java.awt .Color"); 81. if (clipboard.isDataFlavorAvailable(flavor)) 82. { 83. Color color = (Color) clipboard.getData(flavor); 84. chooser.setColor(color); 85. } 86. } 87. catch (ClassNotFoundException e) 88. { 89. JOptionPane.showMessageDialog(this, e); 90. } 91. catch (UnsupportedFlavorException e) 92. { 93. JOptionPane.showMessageDialog(this, e); 94. } 95. catch (IOException e) 96. { 97. JOptionPane.showMessageDialog(this, e); 98. } 99. } 100. 101. private JColorChooser chooser; 102. } 103. 104. /** 105. This class is a wrapper for the data transfer of serialized objects. 106. */ 107. class SerialSelection implements Transferable 108. { 109. /** 110. Constructs the selection. 111. @param o any serializable object 112. */ 113. SerialSelection(Serializable o) 114. { 115. obj = o; 116. } 117. 118. public DataFlavor[] getTransferDataFlavors() 119. { 120. DataFlavor[] flavors = new DataFlavor[2]; 121. Class type = obj.getClass(); 122. String mimeType = "application/x-java-serialized-object;application".equals(flavor.getPrimaryType()) 140. && "x-java-serialized-object".equals(flavor.getSubType()) 141. && flavor.getRepresentationClass().isAssignableFrom(obj.getClass()); 142. } 143. 144. public Object getTransferData(DataFlavor flavor) 145. throws UnsupportedFlavorException 146. { 147. if (!isDataFlavorSupported(flavor)) 148. throw new UnsupportedFlavorException(flavor); 149. 150. if (DataFlavor.stringFlavor.equals(flavor)) 151. return obj.toString(); 152. 153. return obj; 154. } 155. 156. private Serializable obj; 157. } |
|