/*
* This example is from the book "Java Foundation Classes in a Nutshell".
* Written by David Flanagan. Copyright (c) 1999 by O'Reilly & Associates.
* You may distribute this source code for non-commercial purposes only.
* You may study, modify, and use this example for any purpose, as long as
* this notice is retained. Note that this example is provided "as is",
* WITHOUT WARRANTY of any kind either expressed or implied.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.List;
/**
* This simple JTextArea subclass allows TransferableColor objects to
* be pasted or dropped into it. It also supports the pasting of
* text, and the dropping of File objects.
*/
public class ColorSink extends JTextArea implements DropTargetListener {
/** Create a new ColorSink object */
public ColorSink() {
// Listen for double clicks. Use them to trigger a paste action.
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) { pastecolor(); e.consume(); }
}
});
// We have to create a DropTarget object to support Drag-and-Drop
// It will listen for drops on top of us, and notify our DropTargetListener
// methods when drag-and-drop related events occur.
setDropTarget(new DropTarget(this, this));
}
// This method is invoked when the user double-clicks on us. It attempts
// to paste a color or text. Note that the JTextArea we extend
// already supports cut-and-paste of text through the Ctrl-V keystroke.
// This adds a different kind of cut-and-paste for demonstration purposes.
public void pastecolor() {
// Get the clipboard, and read its contents
Clipboard c = this.getToolkit().getSystemClipboard();
Transferable t = c.getContents(this);
if (t == null) { // If nothing to paste
this.getToolkit().beep(); // then beep and do nothing
return;
}
try {
// If the clipboard contained a color, use it as the background color
if (t.isDataFlavorSupported(TransferableColor.colorFlavor)) {
Color color = (Color) t.getTransferData(TransferableColor.colorFlavor);
this.setBackground(color);
}
// If the clipboard contained text, insert it.
else if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
String s = (String) t.getTransferData(DataFlavor.stringFlavor);
this.replaceSelection(s);
}
// Otherwise, we don't know how to paste the data, so just beep.
else this.getToolkit().beep();
}
catch (UnsupportedFlavorException ex) { this.getToolkit().beep(); }
catch (IOException ex) { this.getToolkit().beep(); }
}
// The methods below are the methods of DropTargetListener.
// They are invoked at various times when something is being
// dragged over us, and allow us an opportunity to respond to the drag
// This is the border we display when the user is dragging over us.
protected static Border dropBorder = new BevelBorder(BevelBorder.LOWERED);
// Something is being dragged over us. If we can support this data type
// tell the drag-and-drop system that we are interested, and display
// a special border to tell the user that we're intereted.
public void dragEnter(DropTargetDragEvent e) {
if (e.isDataFlavorSupported(TransferableColor.colorFlavor) ||
e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
e.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
this.setBorder(dropBorder);
}
}
/** The user is no longer dragging over us, so restore the default border */
public void dragExit(DropTargetEvent e) { this.setBorder(null); }
/** This method is invoked when the user drops something on us */
public void drop(DropTargetDropEvent e){
this.setBorder(null); // Restore the default border
Transferable t = e.getTransferable(); // Get the data that was dropped
// Check for types of data that we support
if (t.isDataFlavorSupported(TransferableColor.colorFlavor)) {
// If it was a color, accept it, and use it as the background color
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
try {
Color c = (Color) t.getTransferData(TransferableColor.colorFlavor);
this.setBackground(c);
e.dropComplete(true);
}
catch (Exception ex) { e.dropComplete(false); }
}
else if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
// If it was a file list, accept it, read the first file in the list
// and display the file contents
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
try {
List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
File f = (File) files.get(0);
BufferedReader in = new BufferedReader(new FileReader(f));
String s;
this.setText("");
while((s = in.readLine()) != null) this.append(s);
e.dropComplete(true);
}
catch (Exception ex) { e.dropComplete(false); }
}
else { // If it wasn't a color or a file list, reject it.
e.rejectDrop();
return;
}
}
// These are unused DropTargetListener methods
public void dragOver(DropTargetDragEvent e) {}
public void dropActionChanged(DropTargetDragEvent e) {}
/** This is a simple test program for ColorSource and ColorSink */
public static void main(String[] args) {
// Create a window
JFrame f = new JFrame("ColorSourceTest");
f.getContentPane().setLayout(new BorderLayout());
// Add some ColorSources
JPanel panel = new JPanel();
f.getContentPane().add(panel, BorderLayout.NORTH);
panel.add(new ColorSource(Color.yellow));
panel.add(new ColorSource(Color.pink));
panel.add(new ColorSource(Color.white));
panel.add(new ColorSource(Color.gray));
// Add a ColorSink
ColorSink sink = new ColorSink();
f.getContentPane().add(sink, BorderLayout.CENTER);
// Pop it all up
f.setSize(400, 300);
f.show();
}
}