// 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 |