11.9.3 使用系统剪贴板传递图像
前面已经介绍了,Transferable
接口代表可以放入剪贴板的传输对象,所以如果希望将图像放入剪贴板内,则必须提供一个Transferable
接口的实现类,该实现类其实很简单,它封装一个image
对象,并且向外表现为imageFlavor
内容。
注意
JDK
为Transferable
接口仅提供了一个StringSelection
实现类,用于封装字符串内容但JDK
在DataFlavor
类中提供了一个imageFlavor
常量,用于代表图像格式的DataFlavor
,并负责执行所有的复杂操作,以便进行Java
图像和剪贴板图像的转换。
下面程序实现了一个ImageSelection
类,该类实现了Transferable
接口,并实现了该接口所包含的三个方法。
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 26 27 28 29 30
| import java.awt.*; import java.awt.datatransfer.*;
public class ImageSelection implements Transferable { private Image image;
public ImageSelection(Image image) { this.image = image; }
public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.imageFlavor }; }
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { if (flavor.equals(DataFlavor.imageFlavor)) { return image; } else { throw new UnsupportedFlavorException(flavor); } }
public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(DataFlavor.imageFlavor); } }
|
有了ImageSelection
封装类后,程序就可以将指定的Image
对象包装成ImageSelection
对象放入剪贴板中。
程序示例 java程序保存位图到剪贴板 粘贴图像到java程序中
下面程序对前面的HandDraw.java
程序进行了改进,改进后的程序允许将用户手绘的图像复制到剪贴板中,也可以把剪贴板里的图像粘贴到该程序中。
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| import java.util.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.awt.datatransfer.*;
public class CopyImage { private Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); java.util.List<Image> imageList = new ArrayList<>(); private final int AREA_WIDTH = 500; private final int AREA_HEIGHT = 400; private int preX = -1; private int preY = -1; PopupMenu pop = new PopupMenu(); MenuItem redItem = new MenuItem("红色"); MenuItem greenItem = new MenuItem("绿色"); MenuItem blueItem = new MenuItem("蓝色"); BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); private Frame f = new Frame("简单手绘程序"); private DrawCanvas drawArea = new DrawCanvas(); private Color foreColor = new Color(255, 0, 0);
public void init() { ActionListener menuListener = e -> { if (e.getActionCommand().equals("绿色")) { foreColor = new Color(0, 255, 0); } if (e.getActionCommand().equals("红色")) { foreColor = new Color(255, 0, 0); } if (e.getActionCommand().equals("蓝色")) { foreColor = new Color(0, 0, 255); } }; redItem.addActionListener(menuListener); greenItem.addActionListener(menuListener); blueItem.addActionListener(menuListener); pop.add(redItem); pop.add(greenItem); pop.add(blueItem); drawArea.add(pop); g.fillRect(0, 0, AREA_WIDTH, AREA_HEIGHT); drawArea.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT)); drawArea.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { if (preX > 0 && preY > 0) { g.setColor(foreColor); g.drawLine(preX, preY, e.getX(), e.getY()); } preX = e.getX(); preY = e.getY(); drawArea.repaint(); } }); drawArea.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { pop.show(drawArea, e.getX(), e.getY()); } preX = -1; preY = -1; } }); f.add(drawArea); Panel p = new Panel(); Button copy = new Button("复制"); Button paste = new Button("粘贴"); copy.addActionListener(event -> { ImageSelection contents = new ImageSelection(image); clipboard.setContents(contents, null); }); paste.addActionListener(event -> { if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) { try { imageList.add((Image) clipboard.getData(DataFlavor.imageFlavor)); drawArea.repaint(); } catch (Exception e) { e.printStackTrace(); } } }); p.add(copy); p.add(paste); f.add(p, BorderLayout.SOUTH); f.pack(); f.setVisible(true); }
public static void main(String[] args) { new CopyImage().init(); }
class DrawCanvas extends Canvas { public void paint(Graphics g) { g.drawImage(image, 0, 0, null); for (Image img : imageList) { g.drawImage(img, 0, 0, null); } } } }
|
上面程序实现图像复制、粘贴的代码也很简单,就是程序中两段粗体字代码部分:第一段粗体字代码实现了图像复制功能,将image
对象封装成ImageSelection
对象,然后调用Clipboard
的setContents()
方法将该对象放入剪贴板中;第二段粗体字代码实现了图像粘贴功能,取出剪贴板中的imageFlavor
内容,返回一个Image
对象,将该Image
对象添加到程序的imageList
集合中。
上面程序中使用了“图层”的概念,使用imageList集合来保存所有粘贴到程序中的Image-一每个Image就是一个图层,重绘Canvas对象时需要绘制imageList集合中的每个image图像。运行上面程序,当用户在程序中绘制了一些图像后,单击“复制”按钮,将看到程序将该图像复制到了系统剪贴板中,如图11.34所示。
图11.34将Java程序中的图像放入系统剪贴板中(未完待续…)
如果在其他程序中复制一块图像区域(由其他程序负责将图片放入系统剪贴板中),然后单击本程序中的“粘贴”按钮,就可以将该图像粘贴到本程序中。如图11.35所示,将其他程序中的图像复制到Java程序中。
图11.35将画图程序中的图像复制到Java程序中