Swing JFC Java

/*
Core SWING Advanced Programming 
By Kim Topley
ISBN: 0 13 083292 8       
Publisher: Prentice Hall  
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.undo.*;
public class UndoExample1 extends JFrame {
  public UndoExample1() {
    super("Undo/Redo Example 1");
  
    pane = new JTextPane();
    pane.setEditable(true);    // Editable
    getContentPane().add(new JScrollPane(pane), "Center");
    // Add a menu bar
    menuBar = new JMenuBar();
    setJMenuBar(menuBar);
    // Populate the menu bar
    createMenuBar();
  }
  public void createMenuBar() {
    // Remove the existing menu items
    int count = menuBar.getMenuCount();
    for (int i = 0; i < count; i++) {
      menuBar.remove(menuBar.getMenu(0));
    }
    // Build the new menu.
    Action[] actions = pane.getActions();
    Hashtable actionHash = new Hashtable();
    count = actions.length;
    for (int i = 0; i < count; i++) {
      actionHash.put(actions[i].getValue(Action.NAME), actions[i]);
    }
    // Add the font menu
    JMenu menu = MenuBuilder.buildMenu("Font", fontSpec, actionHash);
    if (menu != null) {
      menuBar.add(menu);
    }
    // Add the alignment menu
    menu = MenuBuilder.buildMenu("Align", alignSpec, actionHash);
    if (menu != null) {
      menuBar.add(menu);
    }
  }
  public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}
  
    JFrame f = new UndoExample1();
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) {
        System.exit(0);
      }
    });
    f.setSize(250, 300);
    f.setVisible(true);
    // Create and show a frame monitoring undoable edits
    JFrame undoMonitor = new JFrame("Undo Monitor");
    final JTextArea textArea = new JTextArea();
    textArea.setEditable(false);
    undoMonitor.getContentPane().add(new JScrollPane(textArea));
    undoMonitor.setBounds(f.getLocation().x + f.getSize().width, 
              f.getLocation().y, 400, 200);
    undoMonitor.setVisible(true);
    pane.getDocument().addUndoableEditListener(new UndoableEditListener() {
      public void undoableEditHappened(UndoableEditEvent evt) {
        UndoableEdit edit = evt.getEdit();
        textArea.append(edit.getPresentationName() + "(" +
                edit.toString() + ")\n");
      }
    });
    
    // Create and show a frame monitoring document edits
    JFrame editMonitor = new JFrame("Edit Monitor");
    final JTextArea textArea2 = new JTextArea();
    textArea2.setEditable(false);
    editMonitor.getContentPane().add(new JScrollPane(textArea2));
    editMonitor.setBounds(undoMonitor.getLocation().x, 
          undoMonitor.getLocation().y + undoMonitor.getSize().height,
          400, 200);
    editMonitor.setVisible(true);
    pane.getDocument().addDocumentListener(new DocumentListener() {
      public void changedUpdate(DocumentEvent evt) {
        textArea2.append("Attribute change\n");
      }
      public void insertUpdate(DocumentEvent evt) {
        textArea2.append("Text insertion\n");
      }
      public void removeUpdate(DocumentEvent evt) {
        textArea2.append("Text removal\n");
      }
    });
  }
  private static JTextPane pane;
  private static JMenuBar menuBar;
  private static MenuSpec[] sizeSpec = new MenuSpec[] {
      new MenuSpec("Size 8",  "font-size-8"),
      new MenuSpec("Size 10", "font-size-10"),
      new MenuSpec("Size 12", "font-size-12"),
      new MenuSpec("Size 14", "font-size-14"),
      new MenuSpec("Size 16", "font-size-16"),
      new MenuSpec("Size 18", "font-size-18"),
      new MenuSpec("Size 24", "font-size-24"),
      new MenuSpec("Size 36", "font-size-36"),
      new MenuSpec("Size 48", "font-size-48")          
  };
  private static MenuSpec[] familySpec = new MenuSpec[] {
      new MenuSpec("Sans Serif", "font-family-SansSerif"),
      new MenuSpec("Monospaced", "font-family-Monospaced"),
      new MenuSpec("Serif", "font-family-Serif")
  };
  private static MenuSpec[] styleSpec = new MenuSpec[] {
      new MenuSpec("Bold", "font-bold"),
      new MenuSpec("Italics", "font-italic"),
      new MenuSpec("Underline", "font-underline")
  };
  // Menu definitions for fonts
  private static MenuSpec[] fontSpec = new MenuSpec[] {
      new MenuSpec("Size", sizeSpec),
      new MenuSpec("Family", familySpec),
      new MenuSpec("Style", styleSpec)
  };
  // Alignment
  private static MenuSpec[] alignSpec = new MenuSpec[] {
      new MenuSpec("Left", "left-justify"),
      new MenuSpec("Center", "center-justify"),
      new MenuSpec("Right", "right-justify")
  };
}
class MenuSpec {
  public MenuSpec(String name, MenuSpec[] subMenus) {
    this.name = name;
    this.subMenus = subMenus;
  }
  public MenuSpec(String name, String actionName) {
    this.name = name;
    this.actionName = actionName;
  }
  public MenuSpec(String name, Action action) {
    this.name = name;
    this.action = action;
  }
  public boolean isSubMenu() {
    return subMenus != null;
  }
  public boolean isAction() {
    return action != null;
  }
  public String getName() {
    return name;
  }
  public MenuSpec[] getSubMenus() {
    return subMenus;
  }
  public String getActionName() {
    return actionName;
  }
  public Action getAction() {
    return action;
  }
  private String name;
  private String actionName;
  private Action action;
  private MenuSpec[] subMenus;
}
class MenuBuilder {
  public static JMenu buildMenu(String name, MenuSpec[] menuSpecs,
      Hashtable actions) {
    int count = menuSpecs.length;
    JMenu menu = new JMenu(name);
    for (int i = 0; i < count; i++) {
      MenuSpec spec = menuSpecs[i];
      if (spec.isSubMenu()) {
        // Recurse to handle a sub menu
        JMenu subMenu = buildMenu(spec.getName(), spec.getSubMenus(),
            actions);
        if (subMenu != null) {
          menu.add(subMenu);
        }
      } else if (spec.isAction()) {
        // It's an Action - add it directly to the menu
        menu.add(spec.getAction());
      } else {
        // It's an action name - add it if possible
        String actionName = spec.getActionName();
        Action targetAction = (Action) actions.get(actionName);
        // Create the menu item
        JMenuItem menuItem = menu.add(spec.getName());
        if (targetAction != null) {
          // The editor kit knows the action
          menuItem.addActionListener(targetAction);
        } else {
          // Action not known - disable the menu item
          menuItem.setEnabled(false);
        }
      }
    }
    // Return null if nothing was added to the menu.
    if (menu.getMenuComponentCount() == 0) {
      menu = null;
    }
    return menu;
  }
}