public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof Timer) {
            // redraw the screen at regular intervals to catch all paint operations
            panel.repaint();
            if (shouldDiff() &&
                System.currentTimeMillis() > createTime + 4 * DELAY) {
                String expected = System.getProperty(DIFF_PROPERTY);
                try {
                    String actual = saveToTempFile();
                    DiffImage diff = new DiffImage(expected, actual);
                    diff.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                } catch (IOException ioe) {
                    System.err.println("Error diffing image: " + ioe);
                }
                timer.stop();
            } else if (shouldSave() && readyToClose()) {
                // auto-save-and-close if desired
                try {
                    if (isAnimated()) {
                        saveAnimated(System.getProperty(SAVE_PROPERTY));
                    } else {
                        save(System.getProperty(SAVE_PROPERTY));
                    }
                } catch (IOException ioe) {
                    System.err.println("Error saving image: " + ioe);
                }
                exit();
            }
        } else if (e.getActionCommand().equals("Exit")) {
            exit();
        } else if (e.getActionCommand().equals("Compare to File...")) {
            compareToFile();
        } else if (e.getActionCommand().equals("Compare to Web File...")) {
            new Thread(new Runnable() {
                public void run() {
                    compareToURL();
                }
            }).start();
        } else if (e.getActionCommand().equals("Save As...")) {
            saveAs();
        } else if (e.getActionCommand().equals("Save Animated GIF...")) {
            saveAsAnimated();
        } else if (e.getActionCommand().equals("Zoom In")) {
            zoom(currentZoom + 1);
        } else if (e.getActionCommand().equals("Zoom Out")) {
            zoom(currentZoom - 1);
        } else if (e.getActionCommand().equals("Zoom Normal (100%)")) {
            zoom(1);
        } else if (e.getActionCommand().equals("Grid Lines")) {
            setGridLines(((JCheckBoxMenuItem) e.getSource()).isSelected());
        } else if (e.getActionCommand().equals("About...")) {
            JOptionPane.showMessageDialog(frame,
                    "DrawingPanel\n" + 
                    "Graphical library class to support Building Java Programs textbook\n" +
                    "written by Marty Stepp and Stuart Reges\n" +
                    "University of Washington\n\n" +
                    "please visit our web site at:\n" +
                    "http://www.buildingjavaprograms.com/",
                    
                    "About DrawingPanel",
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }