FileDocCategorySizeDatePackage
TransferableScribblePane.javaAPI DocExample14118Sat Jan 24 10:44:38 GMT 2004je3.datatransfer

TransferableScribblePane

public class TransferableScribblePane extends JComponent
This rewrite of ScribblePane allows individual PolyLine lines to be selected, cut, copied, pasted, dragged, and dropped.

Fields Summary
List
lines
je3.graphics.PolyLine
currentLine
je3.graphics.PolyLine
selectedLine
boolean
canDragImage
static Stroke
stroke
static Stroke
selectedStroke
static Border
normalBorder
static Border
canDropBorder
public DragGestureListener
dragGestureListener
This DragGestureListener is notified when the user initiates a drag. We passed it to the DragGestureRecognizer we created in the constructor.
public DragSourceListener
dragSourceListener
If this component is the source of a drag, then this DragSourceListener will receive notifications about the progress of the drag. The only one we use here is dragDropEnd() which is called after a drop occurs. We could use the other methods to change cursors or perform other "drag over effects"
public DropTargetListener
dropTargetListener
This DropTargetListener is notified when something is dragged over this component.
Constructors Summary
public TransferableScribblePane()


    // The constructor method
      
	setPreferredSize(new Dimension(450,200)); // We need a default size
	setBorder(normalBorder);                  // and a border.
	lines = new ArrayList();  // Start with an empty list of lines

	// Register interest in mouse button and mouse motion events.
	enableEvents(AWTEvent.MOUSE_EVENT_MASK |
		     AWTEvent.MOUSE_MOTION_EVENT_MASK);

	// Enable drag-and-drop by specifying a listener that will be 
	// notified when a drag begins.  dragGestureListener is defined later.
	DragSource dragSource = DragSource.getDefaultDragSource();
	dragSource.createDefaultDragGestureRecognizer(this,
				     DnDConstants.ACTION_COPY_OR_MOVE,
						      dragGestureListener);

	// Enable drops on this component by registering a listener to 
	// be notified when something is dragged or dropped over us.
	this.setDropTarget(new DropTarget(this, dropTargetListener));

	// Check whether the system allows us to drag an image of the line
	canDragImage = dragSource.isDragImageSupported();
    
Methods Summary
public voidclear()
Erase all lines and repaint.

	lines.clear();
	repaint();
    
public voidcopy()
Copy the selected line to the clipboard

	if (selectedLine == null) return; // Only works if a line is selected
	// Get the system Clipboard object.
	Clipboard c = this.getToolkit().getSystemClipboard();

	// Wrap the selected line in a TransferablePolyLine object
	// and pass it to the clipboard, with an object to receive notification
	// when some other application takes ownership of the clipboard
	c.setContents(new TransferablePolyLine((PolyLine)selectedLine.clone()),
		      new ClipboardOwner() {
			 public void lostOwnership(Clipboard c,Transferable t){
			     // This method is called when something else
			     // is copied to the clipboard.  We could use it
			     // to deselect the selected line, if we wanted.
			 }
		      });
    
public voidcut()
Copy the selected line to the clipboard, then delete it

	if (selectedLine == null) return; // Only works if a line is selected
	copy();                           // Do a Copy operation...
	lines.remove(selectedLine);       // and then erase the selected line
	selectedLine = null;
	repaint();                        // Repaint because a line was removed
    
public voidpaintComponent(java.awt.Graphics g)
We override this method to draw ourselves.

	// Let the superclass do its painting first
	super.paintComponent(g);

	// Make a copy of the Graphics context so we can modify it
	Graphics2D g2 = (Graphics2D) (g.create()); 

	// Our superclass doesn't paint the background, so do this ourselves.
	g2.setColor(getBackground());
	g2.fillRect(0, 0, getWidth(), getHeight());

	// Set the line width and color to use for the foreground
	g2.setStroke(stroke);
	g2.setColor(this.getForeground());

	// Now loop through the PolyLine shapes and draw them all
	int numlines = lines.size();
	for(int i = 0; i < numlines; i++) {
	    PolyLine line = (PolyLine)lines.get(i);
	    if (line == selectedLine) {        // If it is the selected line
		g2.setStroke(selectedStroke);  // Set dash pattern
		g2.draw(line);                 // Draw the line
		g2.setStroke(stroke);          // Revert to solid lines
	    }
	    else g2.draw(line);  // Otherwise just draw the line
	}
    
public voidpaste()
Get a PolyLine from the clipboard, if one exists, and display it

	// Get the system Clipboard and ask for its Transferable contents
	Clipboard c = this.getToolkit().getSystemClipboard(); 
	Transferable t = c.getContents(this);

	// See if we can extract a PolyLine from the Transferable object
	PolyLine line;
	try {
	    line = (PolyLine)t.getTransferData(TransferablePolyLine.FLAVOR);
	}
	catch(Exception e) {  // UnsupportedFlavorException or IOException
	    // If we get here, the clipboard doesn't hold a PolyLine we can use
	    getToolkit().beep();   // So beep to indicate the error
	    return;
	}
	
	lines.add(line); // We got a line from the clipboard, so add it to list
	repaint();       // And repaint to make the line appear
    
public voidprocessMouseEvent(java.awt.event.MouseEvent e)
This method is called on mouse button events. It begins a new line or tries to select an existing line.

	if (e.getButton() == MouseEvent.BUTTON1) {         // Left mouse button
	    if (e.getID() == MouseEvent.MOUSE_PRESSED) {   // Pressed down 
		if (e.isShiftDown()) {                     // with Shift key
		    // If the shift key is down, try to select a line
		    int x = e.getX();
		    int y = e.getY();
		
		    // Loop through the lines checking to see if we hit one
		    PolyLine selection = null;
		    int numlines = lines.size();
		    for(int i = 0; i < numlines; i++) {
			PolyLine line = (PolyLine)lines.get(i);
			if (line.intersects(x-2, y-2, 4, 4)) {
			    selection = line;
			    e.consume();
			    break;
			}
		    }
		    // If we found an intersecting line, save it and repaint
		    if (selection != selectedLine) { // If selection changed
			selectedLine = selection; // remember which is selected
			repaint();                // will make selection dashed
		    }
		}
		else if (!e.isControlDown()) {   // no shift key or ctrl key
		    // Start a new line on mouse down without shift or ctrl
		    currentLine = new PolyLine(e.getX(), e.getY());
		    lines.add(currentLine);
		    e.consume();
		}
	    }
	    else if (e.getID() == MouseEvent.MOUSE_RELEASED) {// Left Button Up
		// End the line on mouse up
		if (currentLine != null) {
		    currentLine = null;
		    e.consume();
		}
	    }
	}

	// The superclass method dispatches to registered event listeners
	super.processMouseEvent(e);
    
public voidprocessMouseMotionEvent(java.awt.event.MouseEvent e)
This method is called for mouse motion events. We don't have to detect gestures that initiate a drag in this method. That is the job of the DragGestureRecognizer we created in the constructor: it will notify the DragGestureListener defined below.

	if (e.getID() == MouseEvent.MOUSE_DRAGGED &&     // If we're dragging
	    currentLine != null) {                       // and a line exists
	    currentLine.addSegment(e.getX(), e.getY());  // Add a line segment
	    e.consume();                                 // Eat the event
	    repaint();                                   // Redisplay all lines
	}
	super.processMouseMotionEvent(e); // Invoke any listeners