FileDocCategorySizeDatePackage
ScribbleCutAndPaste.javaAPI DocExample4628Sat Jun 02 02:43:34 BST 2001None

ScribbleCutAndPaste.java

// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)
// Copyright (c) 1997 by David Flanagan
// This example is provided WITHOUT ANY WARRANTY either expressed or implied.
// You may study, use, modify, and distribute it for non-commercial purposes.
// For any commercial use, see http://www.davidflanagan.com/javaexamples

import java.awt.*;               
import java.awt.event.*;
import java.awt.datatransfer.*;  // Clipboard, Transferable, DataFlavor, etc.
import java.util.Vector;         // To store the scribble in

/** 
 * This class demonstrates how to implement cut-and-paste of data 
 * other than strings.  It is a variant of the Scribble program we've
 * seen so much.  Only about a third of this code is directly cut-and-paste
 * code.  The rest is support code to make this an interesting example
 **/
public class ScribbleCutAndPaste extends Frame {
  /** A very simple main() method for our program. */
  public static void main(String[] args) { new ScribbleCutAndPaste(); }

  /** 
   * Remember # of open windows so we can quit when the last one is closed 
   * We support multiple windows so that we can cut-and-paste among them.
   **/
  protected static int num_windows = 0;

  /** Create a Frame, Menu, and ScrollPane for the scribble component */
  public ScribbleCutAndPaste() {
    super("ScribbleCutAndPaste");            // Create the window
    num_windows++;                           // Count it

    // Create scribble area and add to the frame
    ScribblePanel scribble = new ScribblePanel(this, 400, 300); 
    this.add(scribble, "Center");

    // Set up a menubar
    MenuBar menubar = new MenuBar();         // Create menubar
    this.setMenuBar(menubar);                // Add it to the frame
    Menu file = new Menu("File");            // Create a File menu
    menubar.add(file);                       // Add to menubar

    // Create three menu items, with menu shortcuts, and add to the menu
    MenuItem n, c, q;
    file.add(n = new MenuItem("New Window", new MenuShortcut(KeyEvent.VK_N)));
    file.add(c = new MenuItem("Close Window",new MenuShortcut(KeyEvent.VK_W)));
    file.addSeparator();
    file.add(q = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q)));

    // Create and register action listener objects for the three menu items
    n.addActionListener(new ActionListener() {     // Open a new window
      public void actionPerformed(ActionEvent e) { new ScribbleCutAndPaste(); }
    });
    c.addActionListener(new ActionListener() {     // Close this window
      public void actionPerformed(ActionEvent e) { close(); }
    });
    q.addActionListener(new ActionListener() {     // Quit the program
      public void actionPerformed(ActionEvent e) { System.exit(0); }
    });

    // Another event listener, this one to handle window close requests
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) { close(); }
    });

    // Set the window size and pop it up
    this.pack();
    this.show();
  }

  /** Close a window.  If this is the last open window, just quit. */
  void close() {
    if (--num_windows == 0) System.exit(0);
    else this.dispose();
  }

  /**
   * This class is a custom component that supports scribbling.  It also has
   * a popup menu that provides access to cut-and-paste facilities.
   **/
  static class ScribblePanel extends Canvas implements ActionListener {
    protected short last_x, last_y;                // Coordinates of last click
    protected Vector lines = new Vector(256,256);  // Store the scribbles
    protected int width, height;                   // The preferred size
    protected PopupMenu popup;                     // The popup menu
    protected Frame frame;                         // The frame we are within
    
    /** This constructor requires a Frame and a desired size */
    public ScribblePanel(Frame frame, int width, int height) {
      this.frame = frame;
      this.width = width;
      this.height = height;
      
      // We handle scribbling with low-level events, so we must specify
      // which events we are interested in.
      this.enableEvents(AWTEvent.MOUSE_EVENT_MASK);
      this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);

      // Create the popup menu.
      String[] labels = new String[] {   "Clear", "Cut", "Copy", "Paste" };
      String[] commands = new String[] { "clear", "cut", "copy", "paste" };
      popup = new PopupMenu();                   // Create the menu
      for(int i = 0; i