6.5. A Data Sink
Example 6-3 shows the
ColorSink class, which is a simple subclass of
the Swing JTextArea class.
ColorSink allows color
objects to be pasted or dropped on it. When either event
occurs, ColorSink
sets its background color to the transferred color object. In
addition, the class allows the pasting of textual data, which it
inserts at the current cursor position. Finally,
ColorSink accepts drops of the
DataFlavor.javaFileListFlavor type. This data
flavor is used when the user drags and drops a file icon. When
a ColorSink receives a drop of this
type, it opens the specified file (which it assumes to be a text
file) and reads and displays its contents.
The pastecolor() method does the work of
transferring a color through cut-and-paste. Again, for
simplicity, the pastecolor()
method is invoked when the user double-clicks on the
ColorSink. The drag-and-drop transfer is
implemented primarily in the drop() method.
Note, however, that dragEnter() and
dragExit() perform a simple drag-under effect
by highlighting the ColorSink border.
The ColorSink class also includes a simple
main() method that shows how it can be combined
with the ColorSource class to create a simple
demonstration of cut-and-paste and drag-and-drop.
Example 6-3. ColorSink.java
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 interested.
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();
}
}
 |  |  |
| 6.4. A Data Source |  | 7. Applets |

Copyright © 2001 O'Reilly & Associates. All rights reserved.
|
|