diff --git a/java/3-5-Clipboard/ClipboardDemo.java b/java/3-5-Clipboard/ClipboardDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..3539ddee087e4ffb32c58e5120c8577f4fc322de --- /dev/null +++ b/java/3-5-Clipboard/ClipboardDemo.java @@ -0,0 +1,161 @@ +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; + +public class ClipboardDemo extends JPanel implements ClipboardOwner { + + private JTextArea textArea; + + public ClipboardDemo() { + + this.setLayout(new FlowLayout()); + + // Create a text area for copy and paste tests + // Note that by default, text widgets will support keyboard shortcuts + // for copy/paste + textArea = new JTextArea(); + textArea.setMinimumSize(new Dimension(300, 150)); + textArea.setPreferredSize(textArea.getMinimumSize()); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + this.add(textArea); + + textArea.setText("Lorem ipsum dolor sit amet, semper dissentiet concludaturque an has, " + + "case vivendo vix an. Probo tempor laoreet quo ad."); + + // Create copy/cut/paste buttons to support manual copying and pasting + JButton copyButton = new JButton("Copy"); + JButton cutButton = new JButton("Cut"); + JButton pasteButton = new JButton("Paste"); + this.add(copyButton); + this.add(cutButton); + this.add(pasteButton); + + // Add action listeners to perform the clipboard operations + copyButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCopy(); + } + }); + + cutButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCut(); + } + }); + + pasteButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doPaste(); + } + }); + } + + private void doCopy() { + + System.out.println(String.format("COPY: `%s`", textArea.getSelectedText())); + + // Get the system clipboard + Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); + + // Create a transferable object encapsulating all the info for the copy + Transferable transferObject = new Transferable() { + + private String text = textArea.getSelectedText(); + + // Returns the copy data + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException ,IOException { + System.out.println(" Transferable.getTransferData as " + flavor); + if (flavor.equals(DataFlavor.stringFlavor)) { + return text; + } + throw new UnsupportedFlavorException(flavor); + } + + // Returns the set of data formats we can provide + public DataFlavor[] getTransferDataFlavors() { + System.out.println(" Transferable.getTransferDataFlavors"); + return new DataFlavor[] { DataFlavor.stringFlavor }; + } + + // Indicates whether we can provide data in the specified format + public boolean isDataFlavorSupported(DataFlavor flavor) { + System.out.println(" Transferable.isDataFlavorSupported: " + flavor); + return flavor.equals(DataFlavor.stringFlavor); + } + }; + + // Now set the contents of the clipboard to our transferable object + // NOTE: The second argument "this" tells the system that this + // object would like to be the owner of the clipboard. + // As such, this object must implement the ClipboardOwner interface + System.out.println("COPY: set system clipboard to Transferable"); + cb.setContents(transferObject, this); + } + + private void doCut() { + + System.out.println("CUT"); + + // cut is just a copy that also removes data from document + doCopy(); + textArea.replaceSelection(""); + } + + private void doPaste() { + + System.out.println("PASTE"); + + // Grab system clipboard + Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + System.out.println(String.format("PASTE: %d available flavours ... ", + systemClipboard.getAvailableDataFlavors().length)); + for (DataFlavor f: systemClipboard.getAvailableDataFlavors()) { + System.out.println(" " + f.getHumanPresentableName() + " " + f.toString()); + } + + // Check if we can get the data as a string + if (systemClipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + System.out.println("PASTE: DataFlavor.stringFlavor available"); + try { + // Grab the data, set our text area to the data + String theText = (String)systemClipboard.getData(DataFlavor.stringFlavor); + textArea.replaceSelection(theText); + System.out.println("PASTE: '" + theText + "'"); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + System.out.println("PASTE: DataFlavor.stringFlavor NOT available"); + } + } + + // Implement the ClipboardOwner interface + public void lostOwnership(Clipboard clipboard, Transferable contents) { + System.out.println("ClipboardOwner: lost clipboard ownership"); + } + + public static void main(String[] args) { + JFrame f = new JFrame("Clipboard"); + f.getContentPane().add(new ClipboardDemo()); + f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + f.pack(); + f.setVisible(true); + } +} diff --git a/java/3-5-Clipboard/DragAndDropDemo.java b/java/3-5-Clipboard/DragAndDropDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..3e7521b3f3f52a66dd52475ca778fa3c1240e9cd --- /dev/null +++ b/java/3-5-Clipboard/DragAndDropDemo.java @@ -0,0 +1,180 @@ +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.io.File; + +import javax.swing.*; +import javax.swing.event.MouseInputAdapter; +import java.awt.event.MouseEvent; + +public class DragAndDropDemo extends JPanel { + + private JLabel imageLabel; + private Image image; + + public DragAndDropDemo() { + + setLayout(new GridLayout()); + + // drag target + imageLabel = new JLabel("", SwingConstants.CENTER); + imageLabel.setBackground(Color.WHITE); + imageLabel.setOpaque(true); + add(imageLabel); + + imageLabel.setTransferHandler(new ImageTransferHandler()); + + // create a drag gesture + DragGesture dg = new DragGesture(); + imageLabel.addMouseListener(dg); // For mouseDragged + imageLabel.addMouseMotionListener(dg); // For mouseReleased + } + + // create an image transfer handler + private class ImageTransferHandler extends TransferHandler { + + protected Transferable createTransferable(JComponent c) { + + System.out.println("Creating Transferable"); + + + return new Transferable() { + + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (flavor.equals(DataFlavor.imageFlavor)) { + System.out.println("getTransferData: " + image); + ImageIcon icon = (ImageIcon)imageLabel.getIcon(); + if(icon != null){ + return icon.getImage(); + }else{ + return null; + } + } + throw new UnsupportedFlavorException(flavor); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { DataFlavor.imageFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.imageFlavor); + } + }; + } + + + public int getSourceActions(JComponent c) { + return TransferHandler.COPY; + } + + public boolean importData(JComponent c, Transferable t) { + System.out.print("importData: "); + JLabel label = (JLabel)c; + + imageLabel.setBackground(Color.WHITE); + + if (t.isDataFlavorSupported(DataFlavor.imageFlavor)) { + + System.out.println("imageFlavour"); + + try { + // Get the data and set our label's image icon to the new image. + // Save a copy of the image so we can support dragging it out + image = (Image)t.getTransferData(DataFlavor.imageFlavor); + + label.setIcon(new ImageIcon(image)); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return true; + + } else if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + System.out.println("javaFileListFlavour"); + + try { + // Get the data and set our label's image icon to the new image. + java.util.List<File> files = (java.util.List<File>) t.getTransferData(DataFlavor.javaFileListFlavor); + File f = files.get(0); + + System.out.println("filePath: " + f.getAbsolutePath()); + ImageIcon iIcon = new ImageIcon(f.getAbsolutePath()); + image = iIcon.getImage(); + imageLabel.setIcon(iIcon); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return true; + } + + System.out.println("rejecting"); + return false; + } + + public boolean canImport(JComponent c, DataFlavor[] transferFlavors) { + + for(int i = 0; i < transferFlavors.length; i++) { + DataFlavor df = transferFlavors[i]; + if (df.equals(DataFlavor.imageFlavor) || + df.equals(DataFlavor.javaFileListFlavor)) { + // feedback to show CAN drag into widget + imageLabel.setBackground(Color.GREEN.brighter()); + return true; + } + } + // feedback to show CAN'T drag into widget + imageLabel.setBackground(Color.RED.brighter()); + return false; + } + + protected void exportDone(JComponent c, Transferable data, int action) { + imageLabel.setBackground(Color.WHITE); + System.out.println("exportDone"); + } + + } + + // A simple recognizer for the drag gesture + // The mouseDragged method is called whenever the mouse button is down and + // the mouse is moving. We only want to initiate drag & drop, for each drag + // gesture. As such, we only take action the first time mouseDragged is called, + // resetting whenever the mouse button is released. + private class DragGesture extends MouseInputAdapter { + + private boolean armed = true; + + public void mouseDragged(MouseEvent e) { + + // Enter the conditional only once, at the start of the drag + if (armed) { + System.out.println("Drag starting"); + + // Initiate drag and drop + JComponent c = (JComponent)e.getSource(); + TransferHandler handler = c.getTransferHandler(); + handler.exportAsDrag(c, e, TransferHandler.COPY); + + armed = false; + } + } + + public void mouseReleased(MouseEvent e) { + // Get ready for the next drag + armed = true; + } + } + + public static void main(String[] args) { + JFrame f = new JFrame("DragAndDropDemo"); + f.setSize(200, 200); + f.getContentPane().add(new DragAndDropDemo()); + f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + f.setVisible(true); + } +} diff --git a/java/3-5-Clipboard/makefile b/java/3-5-Clipboard/makefile new file mode 100644 index 0000000000000000000000000000000000000000..ba8e39c7083b6038edaa41c98d2807f924a74f84 --- /dev/null +++ b/java/3-5-Clipboard/makefile @@ -0,0 +1,15 @@ +# super simple makefile +# call it using 'make NAME=name_of_code_file_without_extension' +# (assumes a .java extension) +NAME = "ClipboardDemo" + +all: + @echo "Compiling..." + javac *.java + +run: all + @echo "Running..." + java $(NAME) + +clean: + rm -rf *.class diff --git a/java/3-5-Clipboard/transferDemo/DragableImage.java b/java/3-5-Clipboard/transferDemo/DragableImage.java new file mode 100644 index 0000000000000000000000000000000000000000..485d8ff9ddbd65692f9a302e1927cbae58359c07 --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/DragableImage.java @@ -0,0 +1,157 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.MouseInputAdapter; + +/* + * A DragableImage displays an image and handles drag-and-drop data transfer. + */ +class DragableImage extends JComponent { + + private Image image; + + /* Create a image using either getImageFromFile or getEmptyImage */ + private DragableImage(Image image) { + super(); + this.image = image; + this.setFocusable(true); + + DragGesture dg = new DragGesture(); + this.addMouseListener(dg); + this.addMouseMotionListener(dg); + this.addFocusListener(new HighlightWhenFocusedListener()); + } + + /* Get an empty image (displays nothing) */ + public static DragableImage getEmptyImage() { + return new DragableImage(null); + } + + /* Get a image from an image file. */ + public static DragableImage getImageFromFile(String path) { + if (path == null) { + return new DragableImage(null); + } + + java.net.URL imageURL = TransferDemo.class.getResource(path); + + if (imageURL == null) { + System.err.println("Resource not found: " + path); + return new DragableImage(null); + } else { + return new DragableImage(new ImageIcon(imageURL, path).getImage()); + } + } + + public void setImage(Image image) { + this.image = image; + this.repaint(); + } + + public Image getImage() { + return this.image; + } + + + protected void paintComponent(Graphics graphics) { + Graphics g = graphics.create(); + + // Draw in our entire space, even if isOpaque is false. + g.setColor(Color.WHITE); + g.fillRect(0, 0, image == null ? 125 : image.getWidth(this), + image == null ? 125 : image.getHeight(this)); + + if (image != null) { + // Draw image at its natural size of 125x125. + g.drawImage(image, 0, 0, this); + } + + // Add a border, red if image currently has focus + if (this.isFocusOwner()) { + g.setColor(Color.RED); + } else { + g.setColor(Color.BLACK); + } + g.drawRect(0, 0, image == null ? 125 : image.getWidth(this), + image == null ? 125 : image.getHeight(this)); + g.dispose(); + } + + class HighlightWhenFocusedListener implements FocusListener { + public void focusGained(FocusEvent e) { + // Draw the component with a red border + // indicating that it has focus. + DragableImage.this.repaint(); + } + + public void focusLost(FocusEvent e) { + // Draw the component with a black border + // indicating that it doesn't have focus. + DragableImage.this.repaint(); + } + + } + + /*---------------------- Drag and Drop support ----------------------*/ + + // MouseInputAdapter implements and provides default methods for + // both MouseListener and MouseMotionListener interfaces. + class DragGesture extends MouseInputAdapter { + private MouseEvent firstMouseEvent = null; + + public void mouseClicked(MouseEvent e) { + // Since the user clicked on us, let's get focus! + requestFocusInWindow(); + } + + public void mousePressed(MouseEvent e) { + + // Don't bother to drag if there is no image. + if (DragableImage.this.image == null) return; + + firstMouseEvent = e; + + // prevent any other listeners from acting on this event + e.consume(); + } + + public void mouseReleased(MouseEvent e) { + firstMouseEvent = null; + } + + public void mouseDragged(MouseEvent e) { + + // Don't bother to drag if the component displays no image. + if (DragableImage.this.image == null) return; + + if (firstMouseEvent != null) { + // prevent other listeners from acting on this event + e.consume(); + + int dx = Math.abs(e.getX() - firstMouseEvent.getX()); + int dy = Math.abs(e.getY() - firstMouseEvent.getY()); + + // Arbitrarily define a 5-pixel shift as the + // official beginning of a drag. + if (dx > 5 || dy > 5) { + // This is a drag, not a click. + + // If they are holding down the control key, COPY rather than MOVE + int ctrlMask = InputEvent.CTRL_DOWN_MASK; + int action = ((e.getModifiersEx() & ctrlMask) == ctrlMask) ? + TransferHandler.COPY : TransferHandler.MOVE; + + // drag transfer setup + JComponent c = (JComponent)e.getSource(); + TransferHandler handler = c.getTransferHandler(); + + // Tell the transfer handler to initiate the drag. + handler.exportAsDrag(c, firstMouseEvent, action); + + firstMouseEvent = null; + } + } + } + } + +} diff --git a/java/3-5-Clipboard/transferDemo/ImageGridPanel.java b/java/3-5-Clipboard/transferDemo/ImageGridPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..b391829fcbc8d8acbbbf5371e0bff67bba060e36 --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/ImageGridPanel.java @@ -0,0 +1,243 @@ +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.io.IOException; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.KeyStroke; + +public class ImageGridPanel extends JPanel implements ClipboardOwner { + + // Show up to 12 images + private DragableImage[] pics = new DragableImage[12]; + + // Data to load images into some of the 12 images. + private String[] picNames = + new String[] { "angry", "happy", "worried", "laughing" }; + + // currently selected image index (-1 if none selected) + private int selectedPic = -1; + + // Buttons to make Cut/Copy/Paste visible + private JButton cutButton = new JButton("Cut"); + private JButton copyButton = new JButton("Copy"); + private JButton pasteButton = new JButton("Paste"); + + public ImageGridPanel() { + super(new BorderLayout()); + this.layoutComponent(); + this.registerControllers(); + } + + private void layoutComponent() { + + JPanel images = new JPanel(new GridLayout(3, 4)); + + for (int i = 0; i < this.pics.length; i++) { + if (i < this.picNames.length) { + this.pics[i] = DragableImage.getImageFromFile("images/" + + picNames[i] + ".jpg"); + } else { + this.pics[i] = DragableImage.getEmptyImage(); + } + images.add(this.pics[i]); + } + this.add(images, BorderLayout.CENTER); + + this.setPreferredSize(new Dimension(630, 520)); + this.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + + // out cut/copy/paste buttons into bottom panel + JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT)); + + buttons.add(cutButton); + buttons.add(copyButton); + buttons.add(pasteButton); + + this.add(buttons, BorderLayout.NORTH); + + } + + private void registerControllers() { + // The transfer handler handles the drag-drop and cut-paste + // infrastructure + ImageTransferHandler picHandler = new ImageTransferHandler(); + // This maintains the index of the currently selected image + // (this.selectedPic) + FocusListener fl = new PicFocusListener(); + + for (int i = 0; i < this.pics.length; i++) { + this.pics[i].setTransferHandler(picHandler); + this.pics[i].addFocusListener(fl); + } + + cutButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCut(); + } + }); + + copyButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCopy(); + } + }); + + pasteButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doPaste(); + } + }); + + } + + // Called when this component no longer owns the clipboard + public void lostOwnership(Clipboard clipboard, Transferable contents) { + System.out.println("Lost clipboard ownership for " + selectedPic); + } + + + /* + * Copy the currently selected image. + */ + private void doCopy() { + + // Get the system clipboard + Clipboard systemClipboard = Toolkit.getDefaultToolkit() + .getSystemClipboard(); + + // Create a transferable object encapsulating all the info for the copy + Transferable transferObject = new ImageTransferable(pics[selectedPic]); + + // Now set the contents of the clipboard to our transferable object + systemClipboard.setContents(transferObject, this); + + } + + private void doCut() { + this.doCopy(); // most of a cut is the same as a copy + this.pics[selectedPic].setImage(null); + } + + private void doPaste() { + + // Grab system clipboard + Clipboard systemClipboard = Toolkit.getDefaultToolkit() + .getSystemClipboard(); + + // For our own edification, print out the data formats available on the + // clipboard + for (DataFlavor flavor : systemClipboard.getAvailableDataFlavors()) { + System.out.println("Flavor: " + flavor); + } + + // Check if we can get the data as an image + if (systemClipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) { + try { + // Grab the data, set the selected image to the provided image + Image img = (Image) systemClipboard + .getData(DataFlavor.imageFlavor); + assert img != null; + this.pics[selectedPic].setImage(img); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /* + * A listener to help us keep track of which image has been selected. + */ + class PicFocusListener implements FocusListener { + public void focusGained(FocusEvent e) { + Component c = e.getComponent(); + for (int i = 0; i < pics.length; i++) { + if (pics[i] == c) { + selectedPic = i; + return; + } + } + assert false; + } + + public void focusLost(FocusEvent e) { + } + } + + + /* + * Create a set of cut/copy/paste menus. They call doCopyOrCut and doPaste. + */ + public JMenuBar createMenuBar() { + JMenuBar menubar = new JMenuBar(); + + JMenu file = new JMenu("File"); + + JMenuItem quit = new JMenuItem("Quit"); + quit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + }); + quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, + ActionEvent.META_MASK)); + file.add(quit); + + JMenu edit = new JMenu("Edit"); + JMenuItem cut = new JMenuItem("Cut"); + cut.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCut(); + } + }); + cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, + ActionEvent.META_MASK)); + + JMenuItem copy = new JMenuItem("Copy"); + copy.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doCopy(); + } + }); + copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, + ActionEvent.META_MASK)); + + JMenuItem paste = new JMenuItem("Paste"); + paste.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doPaste(); + } + }); + paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, + ActionEvent.META_MASK)); + + edit.add(cut); + edit.add(copy); + edit.add(paste); + + menubar.add(file); + menubar.add(edit); + return menubar; + } +} diff --git a/java/3-5-Clipboard/transferDemo/ImageTransferHandler.java b/java/3-5-Clipboard/transferDemo/ImageTransferHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..fe31ebd78158ada0ded8be5ddeaf0ed55944d7b1 --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/ImageTransferHandler.java @@ -0,0 +1,87 @@ +import java.io.*; +import java.awt.*; +import java.awt.datatransfer.*; +import javax.swing.*; +import java.util.List; + +class ImageTransferHandler extends TransferHandler { + + DragableImage sourceImage; + boolean shouldRemove; + + /* + * Can we import one of the flavors provided? + */ + public boolean canImport(JComponent c, DataFlavor[] flavors) { + for (int i = 0; i < flavors.length; i++) { + if (flavors[i].equals(DataFlavor.imageFlavor) || + flavors[i].equals(DataFlavor.javaFileListFlavor)) { + return true; + } + } + return false; + } + + /* + * Import the data from the transferable to the component. + */ + public boolean importData(JComponent c, Transferable t) { + Image image; + if (canImport(c, t.getTransferDataFlavors())) { + DragableImage dragableImage = (DragableImage)c; + //Don't drop on myself. + if (sourceImage == dragableImage) { + shouldRemove = false; + return true; + } + + try { + if (t.isDataFlavorSupported(DataFlavor.imageFlavor)) { + image = (Image)t.getTransferData(DataFlavor.imageFlavor); + } else if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor); + File f = files.get(0); + ImageIcon iIcon = new ImageIcon(f.getAbsolutePath()); + image = iIcon.getImage(); + } else { + image = null; // assure compiler everything was initialized + assert false; + } + //Set the component to the new image. + dragableImage.setImage(image); + return true; + } catch (UnsupportedFlavorException ufe) { + System.out.println("importData: unsupported data flavor"); + } catch (IOException ioe) { + System.out.println("importData: I/O exception"); + } + } + return false; + } + + /* + * What kinds of drag actions can we support? + */ + public int getSourceActions(JComponent c) { + return COPY_OR_MOVE; + } + + /* + * Create a transferable to drag somewhere else. + */ + protected Transferable createTransferable(JComponent c) { + sourceImage = (DragableImage)c; + shouldRemove = true; + return new ImageTransferable(sourceImage); + } + + /* + * Finish the export. + */ + protected void exportDone(JComponent c, Transferable data, int action) { + if (shouldRemove && (action == MOVE)) { + sourceImage.setImage(null); + } + sourceImage = null; + } +} diff --git a/java/3-5-Clipboard/transferDemo/ImageTransferable.java b/java/3-5-Clipboard/transferDemo/ImageTransferable.java new file mode 100644 index 0000000000000000000000000000000000000000..93db6945fa05c224f530db7d11b2bdcaa8dea5de --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/ImageTransferable.java @@ -0,0 +1,33 @@ +import java.awt.Image; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; + +/* + * Transfer an image from one source to another. + */ +public class ImageTransferable implements Transferable { + + private Image image; + + ImageTransferable(DragableImage pic) { + image = pic.getImage(); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + return image; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { DataFlavor.imageFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.imageFlavor); + } +} + diff --git a/java/3-5-Clipboard/transferDemo/TransferDemo.java b/java/3-5-Clipboard/transferDemo/TransferDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..9fe21f1ecce61a1af26602db47b1ec9b8a6a9903 --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/TransferDemo.java @@ -0,0 +1,59 @@ +/* + * This demo started life as part of Sun's Java Tutorial for Drag and Drop/Cut and Paste. + * The tutorial had already been updated to Java 6 (which includes changes to + * TransferHandler that I didn't want to use yet), so a cached version was found + * at http://mockus.us/optimum/JavaTutorial/mustang/uiswing/dnd/examples/index.html#DragPictureDemo + * (retrieved June 17, 2009). + * + * It was modified by Byron Weber Becker as follows: + * -- code to initialize the pictures was simplified with an array and loop + * -- removed unused imports + * -- used inner classes for listeners rather than exposing the + * methods in a class's public interface + * -- there were funny inheritance interactions between DragablePicture and Picture + * in the mouse and mousemotion listeners, so combined the two classes + * -- added support for the javaFileList data flavor, enabling drag 'n drop + * from the desktop and to other applications such as image editors + * -- removed the copy/cut/paste magic using action maps and the automatic + * stuff in TransferHandler and replaced it with direct and easier to + * understand implementations. + */ + +import javax.swing.*; + +public class TransferDemo { + + /** + * Create the GUI and show it. For thread safety, + * this method should be invoked from the + * event-dispatching thread. + */ + private static void createAndShowGUI() { + + //Create and set up the window. + JFrame frame = new JFrame("TransferDemo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + //Create and set up the menu bar and content pane. + ImageGridPanel demo = new ImageGridPanel(); + frame.setContentPane(demo); + frame.setJMenuBar(demo.createMenuBar()); + + //Display the window. + frame.pack(); + frame.setVisible(true); + } + + public static void main(String[] args) { + System.out.println("You may need to copy the images directory from the"); + System.out.println("source code directory to the same directory as TransferDemo.class."); + + //Schedule a job for the event-dispatching thread: + //creating and showing this application's GUI. + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + } +} diff --git a/java/3-5-Clipboard/transferDemo/images/angry.jpg b/java/3-5-Clipboard/transferDemo/images/angry.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8286039b09faa546c59143feb6ffcfe59f04e9da Binary files /dev/null and b/java/3-5-Clipboard/transferDemo/images/angry.jpg differ diff --git a/java/3-5-Clipboard/transferDemo/images/happy.jpg b/java/3-5-Clipboard/transferDemo/images/happy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b090961235515ac0abf7531a1b66c6dc83b198b5 Binary files /dev/null and b/java/3-5-Clipboard/transferDemo/images/happy.jpg differ diff --git a/java/3-5-Clipboard/transferDemo/images/laughing.jpg b/java/3-5-Clipboard/transferDemo/images/laughing.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f61710e418ed865e9b205f28cbb0c34b15f7697b Binary files /dev/null and b/java/3-5-Clipboard/transferDemo/images/laughing.jpg differ diff --git a/java/3-5-Clipboard/transferDemo/images/worried.jpg b/java/3-5-Clipboard/transferDemo/images/worried.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4e71289d3de7fe3691244ddddb4caa17edd77747 Binary files /dev/null and b/java/3-5-Clipboard/transferDemo/images/worried.jpg differ diff --git a/java/3-5-Clipboard/transferDemo/makefile b/java/3-5-Clipboard/transferDemo/makefile new file mode 100644 index 0000000000000000000000000000000000000000..5c951d0c89b7875b3efd389d117b3299ce77cf76 --- /dev/null +++ b/java/3-5-Clipboard/transferDemo/makefile @@ -0,0 +1,15 @@ +# super simple makefile +# call it using 'make NAME=name_of_code_file_without_extension' +# (assumes a .java extension) +NAME = "TransferDemo" + +all: + @echo "Compiling..." + javac $(NAME).java + +run: all + @echo "Running..." + java $(NAME) + +clean: + rm -rf *.class