001: package snow.screenshot;
002:
003: import java.text.DecimalFormat;
004: import java.text.NumberFormat;
005: import javax.swing.border.EmptyBorder;
006: import java.awt.*;
007: import java.awt.image.*;
008: import java.awt.event.*;
009: import javax.swing.*;
010: import javax.swing.event.*;
011: import java.io.*;
012: import java.awt.datatransfer.*;
013: import java.util.prefs.Preferences;
014: import snow.utils.gui.*;
015: import java.util.*;
016: import javax.imageio.*;
017:
018: /** A general purpose screenshot utility, with export to file, clipboard and film options.
019: */
020: public class ScreenShot implements MouseMotionListener, MouseListener {
021: // to make the screenshot
022: final private Robot robot = new Robot(); // throws an exception (in the constructor !!!)
023:
024: final private JFrame mainFrame = new JFrame("ScreenShot");
025: final private JDialog up;
026: final private JDialog left;
027: final private JDialog right;
028: final private JDialog down;
029:
030: final private JCheckBoxMenuItem fullScreenMode = new JCheckBoxMenuItem(
031: "Ignore size, take fullscreen", false);
032:
033: final private JCheckBoxMenuItem alwaysOnTop = new JCheckBoxMenuItem(
034: "always on top", true);
035:
036: private int x, y, w, h;
037: int border = 12;
038:
039: private int clickedX = -1, clickedY = -1;
040: private int clickedW = -1, clickedH = -1;
041:
042: private final JLabel titleLabel = new JLabel("ScreenShot frame",
043: JLabel.CENTER);
044: private final JLabel sizeLabel = new JLabel("", JLabel.RIGHT);
045:
046: private JDialog filmDialog = null;
047: final private JPanel filmParamPanel = new JPanel();
048: // used in the mode "save only if changed".
049: private BufferedImage previousShot = null;
050:
051: final boolean standalone;
052:
053: public ScreenShot(final boolean standalone) throws Exception {
054: super ();
055:
056: boolean remember = JDialog.isDefaultLookAndFeelDecorated();
057: JDialog.setDefaultLookAndFeelDecorated(false);
058: up = new JDialog(mainFrame);
059: left = new JDialog(mainFrame);
060: right = new JDialog(mainFrame);
061: down = new JDialog(mainFrame);
062:
063: JDialog.setDefaultLookAndFeelDecorated(remember);
064:
065: mainFrame.setUndecorated(true); // must be called early ! this allow to "hide" the frame but keep his entry as application !
066:
067: this .standalone = standalone;
068: setSize(new Rectangle(100, 100, 400, 300));
069:
070: up.setUndecorated(true);
071: up.addMouseListener(this );
072: up.addMouseMotionListener(this );
073:
074: down.setUndecorated(true);
075: down.addMouseListener(this );
076: down.addMouseMotionListener(this );
077:
078: right.setUndecorated(true);
079: right.addMouseListener(this );
080: right.addMouseMotionListener(this );
081:
082: left.setUndecorated(true);
083: left.addMouseListener(this );
084: left.addMouseMotionListener(this );
085:
086: up.setLayout(new BorderLayout(0, 0));
087: up.add(titleLabel, BorderLayout.CENTER);
088:
089: JPanel shotPanel = new JPanel(new FlowLayout(FlowLayout.LEFT,
090: 0, 0));
091: shotPanel.setBorder(null);
092: up.add(shotPanel, BorderLayout.WEST);
093: JButton bt = new JButton("to clip");
094: shotPanel.add(bt);
095: bt.setBackground(Color.orange);
096: bt.setBorder(null);
097: bt.setMargin(new Insets(0, 0, 0, 0));
098:
099: bt.addActionListener(new ActionListener() {
100: public void actionPerformed(ActionEvent ae) {
101: copyToClipboard();
102: }
103: });
104:
105: JButton tofile = new JButton("to file");
106: tofile.setBackground(Color.orange);
107: tofile.setBorder(null);
108: shotPanel.add(new JLabel(" "));
109: shotPanel.add(tofile);
110: tofile.addActionListener(new ActionListener() {
111: public void actionPerformed(ActionEvent ae) {
112: saveToFile();
113: }
114: });
115:
116: JButton film = new JButton("film");
117: film.setBackground(Color.orange);
118: film.setBorder(null);
119: shotPanel.add(new JLabel(" "));
120: shotPanel.add(film);
121: film.addActionListener(new ActionListener() {
122: public void actionPerformed(ActionEvent ae) {
123: filmAction();
124: }
125: });
126:
127: down.setLayout(new BoxLayout(down.getContentPane(),
128: BoxLayout.X_AXIS));
129:
130: JButton clBT = new JButton(Icons.sharedCross);
131: //clBT.setBackground(Color.orange);
132: clBT.setFocusPainted(false);
133: clBT.setMargin(new Insets(0, 0, 0, 0));
134: down.add(clBT);
135:
136: clBT.addActionListener(new ActionListener() {
137: public void actionPerformed(ActionEvent ae) {
138: terminate();
139: }
140: });
141:
142: final JButton settings = new JButton("opts");
143: settings.setBackground(Color.orange);
144: settings.setBorder(null);
145: down.add(Box.createHorizontalStrut(10));
146: down.add(settings);
147:
148: settings.addActionListener(new ActionListener() {
149: public void actionPerformed(ActionEvent ae) {
150: viewSettings(settings);
151: }
152: });
153:
154: down.add(Box.createHorizontalGlue());
155: down.add(sizeLabel);
156:
157: alwaysOnTop.addActionListener(new ActionListener() {
158: public void actionPerformed(ActionEvent ae) {
159: mainFrame.setAlwaysOnTop(alwaysOnTop.isSelected());
160: }
161: });
162:
163: mainFrame.addWindowListener(new WindowListener() {
164: public void windowClosed(WindowEvent we) {
165: terminate();
166: }
167:
168: public void windowClosing(WindowEvent we) {
169: terminate();
170: }
171:
172: public void windowDeactivated(WindowEvent we) {
173: }
174:
175: public void windowActivated(WindowEvent we) {
176: }
177:
178: public void windowDeiconified(WindowEvent we) {
179: }
180:
181: public void windowIconified(WindowEvent we) {
182: }
183:
184: public void windowOpened(WindowEvent we) {
185: }
186: });
187:
188: KeyListener kl = new KeyAdapter() {
189: @Override
190: public void keyPressed(KeyEvent ke) {
191: int n = 1; // move one pixel at a time
192: if (ke.isShiftDown()) {
193: n = 20; // boost when shift pressed.
194: }
195:
196: if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
197: x -= n;
198: updatePositionAndSize();
199: } else if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
200: x += n;
201: updatePositionAndSize();
202: } else if (ke.getKeyCode() == KeyEvent.VK_UP) {
203: y -= n;
204: updatePositionAndSize();
205: } else if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
206: y += n;
207: updatePositionAndSize();
208: } else if (ke.getKeyCode() == KeyEvent.VK_0
209: || ke.getKeyCode() == KeyEvent.VK_NUMPAD0) {
210: x = 0;
211: y = 0;
212: updatePositionAndSize();
213: } else if (ke.getKeyCode() == KeyEvent.VK_HOME) {
214: x = 0;
215: updatePositionAndSize();
216: } else if (ke.getKeyCode() == KeyEvent.VK_END) {
217: x = Toolkit.getDefaultToolkit().getScreenSize().width
218: - w;
219: updatePositionAndSize();
220: } else if (ke.getKeyCode() == KeyEvent.VK_PAGE_UP) {
221: y = 0;
222: updatePositionAndSize();
223: } else if (ke.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
224: y = Toolkit.getDefaultToolkit().getScreenSize().height
225: - h;
226: updatePositionAndSize();
227: } else if (ke.getKeyCode() == KeyEvent.VK_MULTIPLY) {
228: h *= 1.1;
229: w *= 1.1;
230: updatePositionAndSize();
231: } else if (ke.getKeyCode() == KeyEvent.VK_DIVIDE) {
232: h = h * 9 / 10;
233: w = w * 9 / 10;
234: updatePositionAndSize();
235: } else if (ke.getKeyCode() == KeyEvent.VK_W) {
236: if (ke.isShiftDown())
237: w -= 1;
238: else
239: w += 1;
240: updatePositionAndSize();
241: } else if (ke.getKeyCode() == KeyEvent.VK_H) {
242: if (ke.isShiftDown())
243: h -= 1;
244: else
245: h += 1;
246: updatePositionAndSize();
247: }
248: }
249: };
250: up.addKeyListener(kl);
251: down.addKeyListener(kl);
252: left.addKeyListener(kl);
253: right.addKeyListener(kl);
254: shotPanel.addKeyListener(kl);
255:
256: up.setVisible(true);
257: down.setVisible(true);
258:
259: left.setVisible(true);
260: right.setVisible(true);
261:
262: mainFrame.setSize(0, 0);
263: mainFrame.setDefaultLookAndFeelDecorated(true);
264: //mainFrame.setState(JFrame.ICONIFIED);
265:
266: mainFrame.setMaximumSize(new Dimension(0, 0));
267: mainFrame.setVisible(true);
268:
269: up.toFront();
270:
271: } // Constructor
272:
273: public void terminate() {
274: if (standalone) {
275: System.exit(0);
276: } else {
277: mainFrame.setVisible(false);
278: }
279: }
280:
281: public void mouseDragged(MouseEvent me) {
282: JDialog src = (JDialog) me.getSource();
283: if (src == up || src == left) {
284: int dx = me.getX() - clickedX;
285: int dy = me.getY() - clickedY;
286:
287: x += dx;
288: y += dy;
289:
290: updatePositionAndSize();
291: } else if (src == down) {
292: int dx = me.getX() - clickedX;
293: int dy = me.getY() - clickedY;
294:
295: w = clickedW + dx;
296: h += dy;
297:
298: if (h < 0) {
299: y = y + h;
300: h = -h;
301: }
302:
303: updatePositionAndSize();
304: } else if (src == right) {
305: int dx = me.getX() - clickedX;
306: int dy = me.getY() - clickedY;
307:
308: w += dx;
309: h = clickedH + dy;
310:
311: if (w < 0) {
312: x = x + w;
313: w = -w;
314: }
315:
316: updatePositionAndSize();
317: }
318: }
319:
320: public void mouseMoved(MouseEvent me) {
321: }
322:
323: public void mousePressed(MouseEvent me) {
324: clickedX = me.getX();
325: clickedY = me.getY();
326: clickedW = w;
327: clickedH = h;
328: }
329:
330: public void mouseReleased(MouseEvent me) {
331: }
332:
333: public void mouseClicked(MouseEvent me) {
334: }
335:
336: public void mouseExited(MouseEvent me) {
337: JDialog src = (JDialog) me.getSource();
338: src.setBackground(Color.gray);
339: src.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
340: }
341:
342: public void mouseEntered(MouseEvent me) {
343: JDialog src = (JDialog) me.getSource();
344: //src.setBackground(Color.red);
345: if (src == up || src == left) {
346: src.setCursor(new Cursor(Cursor.MOVE_CURSOR));
347: } else if (src == right) {
348: src.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
349: } else if (src == down) {
350: src.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
351: }
352: }
353:
354: public void setSize(Rectangle rect) {
355: x = (int) rect.getX();
356: y = (int) rect.getY();
357:
358: w = rect.width;
359: h = rect.height;
360:
361: updatePositionAndSize();
362: }
363:
364: private void updatePositionAndSize() {
365: sizeLabel.setText("" + w + " x " + h);
366:
367: up.setLocation(x - border, y - border);
368: left.setLocation(x - border, y);
369:
370: right.setLocation(x + w, y);
371: down.setLocation(x - border, y + h);
372:
373: up.setSize(w + 2 * border, border);
374: down.setSize(w + 2 * border, border);
375:
376: right.setSize(border, h);
377: left.setSize(border, h);
378:
379: }
380:
381: public static void main(String[] aa) {
382: JFrame.setDefaultLookAndFeelDecorated(true);
383: JDialog.setDefaultLookAndFeelDecorated(true);
384: try {
385: ScreenShot sc = new ScreenShot(true);
386: } catch (Exception e) {
387: e.printStackTrace();
388: }
389:
390: }
391:
392: /** All captures are done here.
393: */
394: public BufferedImage capture() {
395: if (fullScreenMode.isSelected()) {
396: Dimension ss = Toolkit.getDefaultToolkit().getScreenSize();
397: return robot.createScreenCapture(new Rectangle(0, 0,
398: ss.width, ss.height));
399: } else {
400: return robot.createScreenCapture(new Rectangle(x, y, w, h));
401: }
402: }
403:
404: public void copyToClipboard() {
405: new ImageCopyToClipboard().copyToClipBoard(this .capture());
406: }
407:
408: public void saveToFile() {
409: BufferedImage bim = this .capture();
410: saveImage(bim, this .up);
411: }
412:
413: volatile boolean doPause = false;
414: volatile long frameNumber = 1;
415:
416: public void filmAction() {
417: if (filmDialog != null) {
418: filmParamPanel.setVisible(true);
419: filmDialog.pack();
420: filmDialog.setVisible(true);
421:
422: return;
423: }
424: filmDialog = new JDialog(up, "Film", false);
425: filmDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
426: //CloseControlPanel ccp = new CloseControlPanel(d, true, true, "Start");
427: //d.add(ccp, BorderLayout.SOUTH);
428: //ccp.getOkButton().setIcon(Icons.StartIcon.shared10);
429: final JLabel status = new JLabel("");
430: JPanel cp = new JPanel();
431: cp.setAlignmentX(1f);
432: cp.setBorder(new EmptyBorder(1, 1, 1, 1));
433: cp.setLayout(new BoxLayout(cp, BoxLayout.X_AXIS));
434: filmDialog.add(cp, BorderLayout.SOUTH);
435: final JButton stop = new JButton(new Icons.StopIcon(10, 10,
436: true));
437: cp.add(status);
438: cp.add(Box.createHorizontalGlue());
439: cp.add(stop);
440: cp.add(Box.createHorizontalStrut(1));
441: final JButton pause = new JButton(new Icons.PauseIcon(10, 10,
442: true));
443: pause.setDisabledIcon(new Icons.PauseIcon(10, 10, false));
444: cp.add(pause);
445: cp.add(Box.createHorizontalStrut(1));
446: final JButton start = new JButton(Icons.sharedSmallStart);
447: cp.add(start);
448: cp.add(Box.createHorizontalStrut(1));
449:
450: stop.setMargin(new Insets(1, 1, 1, 1));
451: pause.setMargin(new Insets(1, 1, 1, 1));
452: start.setMargin(new Insets(1, 1, 1, 1));
453:
454: GridLayout3 gl3 = new GridLayout3(2, filmParamPanel);
455: filmDialog.add(filmParamPanel, BorderLayout.CENTER);
456:
457: String def = "";
458: try {
459: def = Preferences.userRoot().get("FilmSaveDest",
460: System.getProperty("user.home", ""));
461: } catch (Exception e) {
462: }
463:
464: final FileField ff = new FileField(def, true,
465: "Choose the film destination",
466: JFileChooser.DIRECTORIES_ONLY);
467:
468: final JTextPane ta = gl3
469: .addExplanationArea("A utility to automatically take screenshots at regular intervals.\n");
470:
471: gl3.add("Storage folder");
472: gl3.add(ff, true);
473: final JTextField nameTF = new JTextField("screen_film_####", 12);
474: gl3.add("File name template");
475: gl3.add(nameTF);
476:
477: gl3.add("Start number");
478: final JTextField startNB = new JTextField("1", 4);
479: gl3.add(startNB);
480:
481: final JComboBox formatCB = new JComboBox(
482: getAvailableImageWriterFormatNames());
483: try {
484: formatCB.setSelectedItem(Preferences.userRoot().get(
485: "FilmImgFormat", "png"));
486: } catch (Exception e) {
487: }
488: gl3.add("Format");
489: gl3.add(formatCB);
490:
491: gl3.add("Speed [FPS]");
492: final JTextField fpsTF = new JTextField("0.5", 4);
493: gl3.add(fpsTF);
494:
495: // A very cool feature, not ?
496: final JCheckBox onlyIfChangedCB = new JCheckBox(
497: "Save only if image changed", false);
498: gl3.add("");
499: gl3.add(onlyIfChangedCB);
500:
501: // TODO: option: max duration [ min, hour, day, week, month, year ]
502:
503: filmDialog.setLocation(up.getLocationOnScreen());
504: filmDialog.pack();
505: filmDialog.setVisible(true); // NOT modal.
506:
507: pause.addActionListener(new ActionListener() {
508: public void actionPerformed(ActionEvent ae) {
509: doPause = !doPause;
510: if (doPause)
511: status.setText("paused.");
512: }
513: });
514:
515: stop.addActionListener(new ActionListener() {
516: public void actionPerformed(ActionEvent ae) {
517: if (filmTimer != null) {
518: filmTimer.cancel();
519: filmTimer = null;
520: }
521: status.setText("stopped.");
522: pause.setEnabled(false);
523: start.setEnabled(true);
524: stop.setEnabled(false);
525: }
526: });
527:
528: start.addActionListener(new ActionListener() {
529: public void actionPerformed(ActionEvent ae) {
530: final File base = ff.getPath();
531:
532: if (base == null)
533: return;
534: doPause = false;
535: pause.setEnabled(true);
536: start.setEnabled(false);
537: stop.setEnabled(true);
538:
539: filmParamPanel.setVisible(false);
540: status.setText("starting film ...");
541: filmDialog.pack();
542:
543: double fps = 1;
544: long periodMillis = 1000;
545: try {
546: fps = Double.parseDouble(fpsTF.getText().trim());
547: periodMillis = (long) (1000 / fps);
548: if (periodMillis < 20)
549: periodMillis = 20; // 50 per sec!
550: } catch (Exception e) {
551: }
552:
553: try {
554: frameNumber = Long.parseLong(startNB.getText()
555: .trim());
556: } catch (Exception e) {
557: }
558:
559: final String form = "" + formatCB.getSelectedItem();
560: try {
561: Preferences.userRoot().put("FilmSaveDest",
562: base.getAbsolutePath());
563: Preferences.userRoot().put("FilmImgFormat", form);
564: } catch (Exception e) {
565: e.printStackTrace();
566: }
567:
568: //
569: final NumberFormat nf = new DecimalFormat("000000");
570: filmTimer = new java.util.Timer();
571: filmTimer.scheduleAtFixedRate(new TimerTask() {
572: public void run() {
573: if (doPause)
574: return;
575:
576: try {
577: String relname = nameTF.getText();
578: relname = relname.replace("####", nf
579: .format(frameNumber)
580: + "." + form);
581: File dest = new File(base, relname);
582: //ta.setText("Writing "+dest);
583: status.setText("frame " + frameNumber); //
584:
585: BufferedImage bim = capture();
586:
587: if (onlyIfChangedCB.isSelected()) {
588: if (previousShot != null) {
589: if (ImageUtils.imageEquals(bim,
590: previousShot))
591: return;
592: }
593:
594: previousShot = bim;
595: }
596:
597: ImageIO.write(bim, form, dest);
598:
599: frameNumber++;
600: } catch (Exception e) {
601: filmTimer.cancel();
602: filmTimer = null;
603:
604: JOptionPane.showMessageDialog(null,
605: "Film error: " + e.getMessage(),
606: "Film error",
607: JOptionPane.ERROR_MESSAGE);
608: e.printStackTrace();
609: }
610: }
611: }, 0, periodMillis);
612:
613: }
614: });
615:
616: pause.setEnabled(false);
617: start.setEnabled(true);
618: stop.setEnabled(false);
619:
620: }
621:
622: java.util.Timer filmTimer = null;
623:
624: private void viewSettings(Component comp) {
625: JPopupMenu pop = new JPopupMenu();
626:
627: pop.add("" + w + " x " + h);
628: pop.addSeparator();
629:
630: pop.add(alwaysOnTop);
631: pop.addSeparator();
632:
633: JMenuItem sh10 = new JMenuItem("shot to clipboard in 10 secs");
634: pop.add(sh10);
635: sh10.addActionListener(new ActionListener() {
636: public void actionPerformed(ActionEvent ae) {
637: Thread t = new Thread() {
638: public void run() {
639: try {
640: Thread.sleep(10000L);
641: } catch (Exception e) {
642: }
643: copyToClipboard();
644: }
645: };
646: t.start();
647: }
648: });
649:
650: JMenuItem tofile2 = new JMenuItem("shot to file in 10 secs");
651: pop.add(tofile2);
652: tofile2.addActionListener(new ActionListener() {
653: public void actionPerformed(ActionEvent ae) {
654: Thread t = new Thread() {
655: public void run() {
656: try {
657: Thread.sleep(10000L);
658: } catch (Exception e) {
659: }
660: saveToFile();
661: }
662: };
663: t.start();
664: }
665: });
666:
667: pop.addSeparator();
668: final int[][] sizes = new int[][] { { 16, 16 }, { 32, 32 },
669: { 48, 48 }, { 64, 64 }, { 320, 240 }, { 640, 480 },
670: { 800, 600 }, { 1024, 768 }, { 1280, 1024 },
671: { 1600, 1200 } };
672: for (final int[] si : sizes) {
673: JMenuItem mi = new JMenuItem("Set size " + si[0] + " x "
674: + si[1]);
675: pop.add(mi);
676: mi.addActionListener(new ActionListener() {
677: public void actionPerformed(ActionEvent ae) {
678: setSize(new Rectangle(x, y, si[0], si[1]));
679: }
680: });
681: }
682:
683: pop.addSeparator();
684: pop.add(fullScreenMode);
685:
686: pop.show(comp, 0, 10);
687: }
688:
689: public static void saveImage(BufferedImage im, Component parent) {
690: String def = "";
691: try {
692: def = Preferences.userRoot().get("ImageSaveDest",
693: System.getProperty("user.home", ""));
694: } catch (Exception e) {
695: }
696:
697: if (im == null) {
698: JOptionPane.showMessageDialog(parent,
699: "Unable to save image, image is null", "Error",
700: JOptionPane.ERROR_MESSAGE);
701: return;
702: }
703:
704: JFileChooser fs = new JFileChooser(def);
705: SaveDialogAccessoryPanel sda = new SaveDialogAccessoryPanel(fs,
706: im);
707:
708: // modal
709: int rep = fs.showSaveDialog(parent);
710:
711: if (rep == JFileChooser.APPROVE_OPTION) {
712: File file = fs.getSelectedFile();
713: String format = (String) sda.formatCB.getSelectedItem();
714: if (!file.getName().toLowerCase().endsWith(
715: "." + format.toLowerCase())) {
716: file = new File(file.getAbsolutePath() + "." + format);
717: }
718:
719: try {
720: ImageIO.write(im, format, file);
721: System.out.println("image saved to " + file);
722:
723: try {
724: Preferences.userRoot().put("ImageSaveDest",
725: file.getParent());
726: } catch (Exception e2) {
727: }
728:
729: } catch (Exception e) {
730: e.printStackTrace();
731: JOptionPane.showMessageDialog(parent,
732: "Unable to save image in " + file
733: + "\nError : " + e.getMessage(),
734: "Error", JOptionPane.ERROR_MESSAGE);
735: }
736: }
737: }
738:
739: static class SaveDialogAccessoryPanel extends JPanel {
740: JComboBox formatCB = new JComboBox(
741: getAvailableImageWriterFormatNames());
742:
743: public SaveDialogAccessoryPanel(final JFileChooser fs,
744: final Image bim) {
745: super ();
746: GridLayout3 gl = new GridLayout3(2, this );
747: gl.add("Format: ");
748: gl.add(formatCB);
749: formatCB.setMaximumRowCount(20);
750: formatCB.setSelectedItem("png");
751:
752: JButton copyToClipboard = new JButton("Copy to clipboard");
753: copyToClipboard.setMargin(new Insets(0, 2, 0, 2));
754: gl.add("");
755: gl.add(copyToClipboard);
756: copyToClipboard.addActionListener(new ActionListener() {
757: public void actionPerformed(ActionEvent ae) {
758: new ImageCopyToClipboard().copyToClipBoard(bim);
759: }
760: });
761:
762: fs.setAccessory(this );
763: }
764: }
765:
766: public static Vector<String> getAvailableImageWriterFormatNames() {
767: Vector<String> formats = new Vector<String>();
768: for (String f : ImageIO.getWriterFormatNames()) {
769: if (!formats.contains(f.toLowerCase())) {
770: formats.add(f.toLowerCase());
771: }
772: }
773: return formats;
774: }
775:
776: static class ImageCopyToClipboard implements ClipboardOwner {
777: public ImageCopyToClipboard() {
778: super ();
779: }
780:
781: public void copyToClipBoard(Image img) {
782: Toolkit tkt = Toolkit.getDefaultToolkit();
783: Clipboard clipboard = tkt.getSystemClipboard();
784: Transferable t = new ImageSelection(img);
785: clipboard.setContents(t, this );
786: }
787:
788: public void lostOwnership(Clipboard clipboard,
789: Transferable contents) {
790: System.out
791: .println("ClipboardSupport.lostOwnership() called");
792: }
793:
794: class ImageSelection implements Transferable {
795: private Image img = null;
796: DataFlavor dataFlavor = DataFlavor.imageFlavor;
797:
798: public ImageSelection(Image img) {
799: super ();
800: this .img = img;
801: }
802:
803: public DataFlavor[] getTransferDataFlavors() {
804: DataFlavor[] data = new DataFlavor[1];
805: data[0] = dataFlavor;
806: return data;
807: }
808:
809: public boolean isDataFlavorSupported(DataFlavor flavor) {
810: if (dataFlavor.equals(flavor)) {
811: return true;
812: } else {
813: return false;
814: }
815: }
816:
817: public Object getTransferData(DataFlavor flavor)
818: throws UnsupportedFlavorException, IOException {
819: return img;
820: }
821:
822: }
823: }
824:
825: }
|