1 package charactermanaj.clipboardSupport;
\r
3 import java.awt.Color;
\r
4 import java.awt.datatransfer.Clipboard;
\r
5 import java.awt.datatransfer.DataFlavor;
\r
6 import java.awt.datatransfer.FlavorMap;
\r
7 import java.awt.datatransfer.SystemFlavorMap;
\r
8 import java.awt.datatransfer.Transferable;
\r
9 import java.awt.datatransfer.UnsupportedFlavorException;
\r
10 import java.awt.image.BufferedImage;
\r
11 import java.io.ByteArrayInputStream;
\r
12 import java.io.ByteArrayOutputStream;
\r
13 import java.io.IOException;
\r
14 import java.io.InputStream;
\r
15 import java.util.Arrays;
\r
16 import java.util.List;
\r
17 import java.util.logging.Level;
\r
18 import java.util.logging.Logger;
\r
20 import javax.imageio.ImageIO;
\r
22 import charactermanaj.graphics.io.ImageSaveHelper;
\r
23 import charactermanaj.model.AppConfig;
\r
26 * クリップボードに画像をコピーするためのセレクション.<br>
\r
29 public class ImageSelection implements Transferable {
\r
34 private static final Logger logger = Logger.getLogger(ImageSelection.class.getName());
\r
39 private static final boolean platformWindows;
\r
44 private BufferedImage img;
\r
49 private Color bgColor;
\r
54 private static final DataFlavor PNG_FLAVOR = new DataFlavor("image/png", "image/png");
\r
59 private static final DataFlavor JPEG_FLAVOR = new DataFlavor("image/jpeg", "image/jpeg");
\r
64 private static final DataFlavor BMP_FLAVOR = new DataFlavor("image/bmp", "image/bmp");
\r
71 private static final List<DataFlavor> SUPPORTED_FLAVORS;
\r
77 String lcOS = System.getProperty("os.name").toLowerCase();
\r
78 platformWindows = lcOS.indexOf("windows") >= 0;
\r
79 if (platformWindows) {
\r
81 SUPPORTED_FLAVORS = Arrays.asList(new DataFlavor[] {
\r
83 DataFlavor.imageFlavor,
\r
87 // Linux, Mac OS Xの場合を想定
\r
88 SUPPORTED_FLAVORS = Arrays.asList(new DataFlavor[] {
\r
92 DataFlavor.imageFlavor,
\r
98 * システムのフレーバーマップを設定する.<br>
\r
99 * @return 正常にセットアップできた場合はtrue、そうでなければfalse
\r
101 public static boolean setupSystemFlavorMap() {
\r
103 AppConfig appConfig = AppConfig.getInstance();
\r
104 if (appConfig.isEnablePNGSupportForWindows()) {
\r
105 // "PNG"へのマップを明示的に設定する.
\r
106 // (Windowsの場合、デフォルトでは、画像はDBI転送となり透過情報を持つことができないため.)
\r
107 FlavorMap defFlavorMap = SystemFlavorMap.getDefaultFlavorMap();
\r
108 if (defFlavorMap instanceof SystemFlavorMap) {
\r
109 SystemFlavorMap sysFlavorMap = (SystemFlavorMap) defFlavorMap;
\r
110 sysFlavorMap.setNativesForFlavor(PNG_FLAVOR, new String[] {"PNG"});
\r
111 sysFlavorMap.setNativesForFlavor(JPEG_FLAVOR, new String[] {"JFIF"});
\r
116 } catch (Exception ex) {
\r
117 logger.log(Level.SEVERE, "systemFlavorMap setup failed.", ex);
\r
124 * @param img 対象となるイメージ
\r
126 public ImageSelection(BufferedImage img, Color bgColor) {
\r
128 throw new IllegalArgumentException();
\r
131 this.bgColor = (bgColor == null) ? Color.white : bgColor;
\r
134 public Object getTransferData(DataFlavor flavor)
\r
135 throws UnsupportedFlavorException, IOException {
\r
136 if (flavor != null) {
\r
137 logger.log(Level.FINE, "getTransferData flavor=" + flavor);
\r
139 ImageSaveHelper imageSaveHelper = new ImageSaveHelper();
\r
141 if (flavor.equals(PNG_FLAVOR) || flavor.equals(JPEG_FLAVOR) || flavor.equals(BMP_FLAVOR)) {
\r
142 // image/png, image/jpeg, image/bmpの場合は、
\r
143 // そのファイル形式のデータを生成して、それを返す.
\r
144 ByteArrayOutputStream bos = new ByteArrayOutputStream();
\r
146 imageSaveHelper.savePicture(img, bgColor, bos, flavor.getMimeType(), null);
\r
151 return new ByteArrayInputStream(bos.toByteArray());
\r
154 if (flavor.equals(DataFlavor.imageFlavor)) {
\r
155 // "image/x-java-image"の場合
\r
156 AppConfig appConfig = AppConfig.getInstance();
\r
157 if (platformWindows || !appConfig.isEnablePNGSupportForWindows()) {
\r
158 // Windowsの場合は、背景色で塗りつぶしたBMP画像に変換して返す.
\r
159 // JDK5/6のシステムクリップボードへのコピーでは透過画像をサポートしておらず透過部分が黒色になるため.
\r
160 // ネイティブPNGとのマッピングが有効であれば、Windowsでは、そちらで対応する.
\r
161 return imageSaveHelper.createBMPFormatPicture(img, bgColor);
\r
164 // Windows以外、且つ、透過サポートが有効の場合
\r
169 } catch (RuntimeException ex) {
\r
170 logger.log(Level.WARNING, "The exception occurred during the data transfer of a clipboard.", ex);
\r
173 } catch (IOException ex) {
\r
174 logger.log(Level.WARNING, "The exception occurred during the data transfer of a clipboard.", ex);
\r
179 throw new UnsupportedFlavorException(flavor);
\r
182 public DataFlavor[] getTransferDataFlavors() {
\r
183 return SUPPORTED_FLAVORS.toArray(new DataFlavor[SUPPORTED_FLAVORS.size()]);
\r
186 public boolean isDataFlavorSupported(DataFlavor flavor) {
\r
187 return flavor != null && SUPPORTED_FLAVORS.contains(flavor);
\r
190 public static boolean isSupprotedFlavorAvailable(Clipboard cb) {
\r
192 for (DataFlavor flavor : SUPPORTED_FLAVORS) {
\r
193 if (cb.isDataFlavorAvailable(flavor)) {
\r
201 public static BufferedImage getImage(Clipboard cb) throws IOException {
\r
206 // サポートされている形式をチェックする.
\r
207 for (DataFlavor flavor : cb.getAvailableDataFlavors()) {
\r
208 logger.log(Level.FINE, "dataFlavor(in Clipboard)=" + flavor);
\r
210 DataFlavor availableFlavor = null;
\r
211 for (DataFlavor flavor : SUPPORTED_FLAVORS) {
\r
212 // 優先順にチェックし最初に見つかったサポートされている形式を採用する.
\r
213 if (cb.isDataFlavorAvailable(flavor)) {
\r
214 availableFlavor = flavor;
\r
218 logger.log(Level.FINE, "selected flavor=" + availableFlavor);
\r
219 if (availableFlavor != null) {
\r
221 if (availableFlavor.equals(DataFlavor.imageFlavor)) {
\r
223 // 透過画像は使えないため、ここで取得されるものは非透過画像である。
\r
224 return (BufferedImage) cb.getData(DataFlavor.imageFlavor);
\r
227 if (availableFlavor.equals(PNG_FLAVOR)
\r
228 || availableFlavor.equals(JPEG_FLAVOR)
\r
229 || availableFlavor.equals(BMP_FLAVOR)) {
\r
230 // image/png, image/bmp, image/jpegのいずれか
\r
232 InputStream is = (InputStream) cb.getData(availableFlavor);
\r
236 img = ImageIO.read(is);
\r
245 } catch (IOException ex) {
\r
246 logger.log(Level.WARNING, "The exception occurred in access to a clipboard.", ex);
\r
249 } catch (UnsupportedFlavorException ex) {
\r
250 // 直前にisDataFlavorAvailableで確認しているので、
\r
251 // よほどタイミングが悪くなければエラーは発生しないはず。
\r
252 logger.log(Level.WARNING, "The exception occurred in access to a clipboard.", ex);
\r
253 throw new IOException(ex.getMessage());
\r
256 // サポートしているものが無い場合.
\r