Mega Code Archive

 
Categories / Java / Swing JFC
 

Add undo support to the StyleFrame example

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O'Reilly  */ // UndoStyleFrame.java //Add undo support to the StyleFrame example. This example only //retains the most recent edit, to keep things simple. import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.SwingConstants; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.undo.UndoableEdit; public class UndoStyleFrame extends StyleFrame {   protected UndoAct undoAction = new UndoAct(); // an Action for undo   protected RedoAct redoAction = new RedoAct(); // an Action for redo   public UndoStyleFrame() {     super();     setTitle("UndoStyleFrame");     // register the Actions as undo listeners (we inherited textPane)     textPane.getDocument().addUndoableEditListener(undoAction);     textPane.getDocument().addUndoableEditListener(redoAction);     // create menu for undo/redo     JMenu editMenu = new JMenu("Edit");     editMenu.add(new JMenuItem(undoAction));     editMenu.add(new JMenuItem(redoAction));     menuBar.add(editMenu); // we inherited menuBar from superclass     // create buttons for undo/redo     JPanel buttonPanel = new JPanel();     buttonPanel.add(new JButton(undoAction));     buttonPanel.add(new JButton(redoAction));     getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH);   }   // begin inner classes ------------   public class UndoAct extends AbstractAction implements UndoableEditListener {     private UndoableEdit edit;     public UndoAct() {       super("Undo");       setEnabled(false);     }     public void updateEnabled() {       setEnabled(edit.canUndo());     }     public void undoableEditHappened(UndoableEditEvent event) {       edit = event.getEdit();       putValue(NAME, edit.getUndoPresentationName());       updateEnabled();     }     public void actionPerformed(ActionEvent ae) {       edit.undo();       updateEnabled(); // disable undo       redoAction.updateEnabled(); // enable redo     }   }   public class RedoAct extends AbstractAction implements UndoableEditListener {     private UndoableEdit edit;     public RedoAct() {       super("Redo");       setEnabled(false);     }     public void updateEnabled() {       setEnabled(edit.canRedo());     }     public void undoableEditHappened(UndoableEditEvent event) {       edit = event.getEdit();       putValue(NAME, edit.getRedoPresentationName());       updateEnabled();     }     public void actionPerformed(ActionEvent ae) {       edit.redo();       updateEnabled(); // disable redo       undoAction.updateEnabled(); // enable undo     }   }   // end inner classes ------------   public static void main(String[] args) {     JFrame frame = new UndoStyleFrame();     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     frame.setSize(400, 300);     frame.setVisible(true);   } } //StyleFrame.java //A JTextPane with a menu for Style manipulation. class StyleFrame extends JFrame implements ActionListener {   protected StyleBox styleBox;   protected JTextPane textPane;   protected JMenuBar menuBar;   protected JMenu applyStyleMenu, modifyStyleMenu;   protected JMenuItem createItem;   public StyleFrame() {     super("StyleFrame");     styleBox = new StyleBox();     textPane = new JTextPane();     getContentPane().add(new JScrollPane(textPane), BorderLayout.CENTER);     // set up menu     menuBar = new JMenuBar();     JMenu styleMenu = new JMenu("Style");     menuBar.add(styleMenu);     setJMenuBar(menuBar);     applyStyleMenu = new JMenu("Set Logical Style");     applyStyleMenu         .setToolTipText("set the Logical Style for the paragraph at caret location");     styleMenu.add(applyStyleMenu);     modifyStyleMenu = new JMenu("Modify Style");     modifyStyleMenu         .setToolTipText("redefine a named Style (will affect paragraphs using that style)");     styleMenu.add(modifyStyleMenu);     createItem = new JMenuItem("Create New Style");     createItem         .setToolTipText("define a new Style (which can then be applied to paragraphs)");     createItem.addActionListener(this);     styleMenu.add(createItem);     // add the default style to applyStyleMenu and modifyStyleMenu     createMenuItems(StyleContext.DEFAULT_STYLE);   }   protected void createMenuItems(String styleName) {     // add 'styleName' to applyStyleMenu and modifyStyleMenu     JMenuItem applyItem = new JMenuItem(styleName);     applyItem.addActionListener(this);     applyStyleMenu.add(applyItem);     JMenuItem modifyItem = new JMenuItem(styleName);     modifyItem.addActionListener(this);     modifyStyleMenu.add(modifyItem);   }   public void actionPerformed(ActionEvent e) {     // determine which menuItem was invoked and process it     JMenuItem source = (JMenuItem) e.getSource();     if (applyStyleMenu.isMenuComponent(source)) {       // apply an existing style to the paragraph at the caret position       String styleName = source.getActionCommand();       Style style = textPane.getStyle(styleName);       textPane.setLogicalStyle(style);     }     if (source == createItem) {       // define a new Style and add it to the menus       styleBox.clear();       int response = JOptionPane.showConfirmDialog(this, styleBox,           "Style Editor", JOptionPane.OK_CANCEL_OPTION,           JOptionPane.PLAIN_MESSAGE);       if (response == JOptionPane.OK_OPTION           && styleBox.getStyleName().length() > 0) {         String styleName = styleBox.getStyleName();         Style style = textPane.addStyle(styleName, null);         styleBox.fillStyle(style);         createMenuItems(styleName); // add new Style to the menus       }     }     if (modifyStyleMenu.isMenuComponent(source)) {       // redefine a Style (will automatically redraw paragraphs using       // Style)       String styleName = source.getActionCommand();       Style style = textPane.getStyle(styleName);       styleBox.loadFromStyle(style);       int response = JOptionPane.showConfirmDialog(this, styleBox,           "Style Editor", JOptionPane.OK_CANCEL_OPTION,           JOptionPane.PLAIN_MESSAGE);       if (response == JOptionPane.OK_OPTION)         styleBox.fillStyle(style);     }   }   public static void main(String[] args) {     JFrame frame = new StyleFrame();     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     frame.setSize(400, 300);     frame.setVisible(true);   } } //StyleBox.java //A control panel that can be used to edit a style's paragraph attributes. class StyleBox extends JPanel {   private static final String[] fonts = { "Monospaced", "Serif", "SansSerif" };   private static final String[] sizes = { "8", "10", "12", "18", "24", "36" };   private JTextField nameField;   private JComboBox fontCombo, sizeCombo;   private JTextField leftField, rightField, aboveField, belowField;   private JCheckBox boldCheck, italicCheck;   public StyleBox() {     // create the fields and lay them out     super(new BorderLayout(4, 4));     JPanel labelPanel = new JPanel(new GridLayout(8, 1, 0, 2));     JPanel valuePanel = new JPanel(new GridLayout(8, 1, 0, 2));     add(labelPanel, BorderLayout.WEST);     add(valuePanel, BorderLayout.CENTER);     JLabel lab;     JPanel sidePanel;     lab = new JLabel("Style Name", SwingConstants.RIGHT);     labelPanel.add(lab);     nameField = new JTextField();     lab.setLabelFor(nameField);     valuePanel.add(nameField);     lab = new JLabel("Font", SwingConstants.RIGHT);     labelPanel.add(lab);     fontCombo = new JComboBox(fonts);     fontCombo.setEditable(true); // user may enter custom value     lab.setLabelFor(fontCombo);     valuePanel.add(fontCombo);     lab = new JLabel("Size", SwingConstants.RIGHT);     labelPanel.add(lab);     sizeCombo = new JComboBox(sizes);     sizeCombo.setEditable(true); // user may enter custom value     lab.setLabelFor(sizeCombo);     sidePanel = new JPanel(new BorderLayout(4, 0));     sidePanel.add(sizeCombo, BorderLayout.CENTER);     sidePanel.add(new JLabel("points"), BorderLayout.EAST);     valuePanel.add(sidePanel);     lab = new JLabel("Left Indent", SwingConstants.RIGHT);     labelPanel.add(lab);     leftField = new JTextField();     lab.setLabelFor(leftField);     sidePanel = new JPanel(new BorderLayout(4, 0));     sidePanel.add(leftField, BorderLayout.CENTER);     sidePanel.add(new JLabel("points"), BorderLayout.EAST);     valuePanel.add(sidePanel);     lab = new JLabel("Right Indent", SwingConstants.RIGHT);     labelPanel.add(lab);     rightField = new JTextField();     lab.setLabelFor(rightField);     sidePanel = new JPanel(new BorderLayout(4, 0));     sidePanel.add(rightField, BorderLayout.CENTER);     sidePanel.add(new JLabel("points"), BorderLayout.EAST);     valuePanel.add(sidePanel);     lab = new JLabel("Space Above", SwingConstants.RIGHT);     labelPanel.add(lab);     aboveField = new JTextField();     lab.setLabelFor(aboveField);     sidePanel = new JPanel(new BorderLayout(4, 0));     sidePanel.add(aboveField, BorderLayout.CENTER);     sidePanel.add(new JLabel("points"), BorderLayout.EAST);     valuePanel.add(sidePanel);     lab = new JLabel("Space Below", SwingConstants.RIGHT);     labelPanel.add(lab);     belowField = new JTextField();     lab.setLabelFor(belowField);     sidePanel = new JPanel(new BorderLayout(4, 0));     sidePanel.add(belowField, BorderLayout.CENTER);     sidePanel.add(new JLabel("points"), BorderLayout.EAST);     valuePanel.add(sidePanel);     boldCheck = new JCheckBox("Bold");     italicCheck = new JCheckBox("Italic");     sidePanel = new JPanel(new GridLayout(1, 2));     sidePanel.add(boldCheck);     sidePanel.add(italicCheck);     valuePanel.add(sidePanel);     clear(); // sets initial values, etc.   }   public void clear() {     // reset all fields (also sets nameField to be editable)     nameField.setText("");     nameField.setEditable(true);     fontCombo.setSelectedIndex(0);     sizeCombo.setSelectedIndex(2);     leftField.setText("0.0");     rightField.setText("0.0");     aboveField.setText("0.0");     belowField.setText("0.0");     boldCheck.setSelected(false);     italicCheck.setSelected(false);   }   public String getStyleName() {     // return the name of the style     String name = nameField.getText();     if (name.length() > 0)       return name;     else       return null;   }   public void fillStyle(Style style) {     // mutate 'style' with the values entered in the fields     // (no value checking--could throw NumberFormatException)     String font = (String) fontCombo.getSelectedItem();     StyleConstants.setFontFamily(style, font);     String size = (String) sizeCombo.getSelectedItem();     StyleConstants.setFontSize(style, Integer.parseInt(size));     String left = leftField.getText();     StyleConstants.setLeftIndent(style, Float.valueOf(left).floatValue());     String right = rightField.getText();     StyleConstants.setRightIndent(style, Float.valueOf(right).floatValue());     String above = aboveField.getText();     StyleConstants.setSpaceAbove(style, Float.valueOf(above).floatValue());     String below = belowField.getText();     StyleConstants.setSpaceBelow(style, Float.valueOf(below).floatValue());     boolean bold = boldCheck.isSelected();     StyleConstants.setBold(style, bold);     boolean italic = italicCheck.isSelected();     StyleConstants.setItalic(style, italic);   }   // Load the form from an existing Style.   public void loadFromStyle(Style style) {     nameField.setText(style.getName());     nameField.setEditable(false); // don't allow name change     String fam = StyleConstants.getFontFamily(style);     fontCombo.setSelectedItem(fam);     int size = StyleConstants.getFontSize(style);     sizeCombo.setSelectedItem(Integer.toString(size));     float left = StyleConstants.getLeftIndent(style);     leftField.setText(Float.toString(left));     float right = StyleConstants.getRightIndent(style);     rightField.setText(Float.toString(right));     float above = StyleConstants.getSpaceAbove(style);     aboveField.setText(Float.toString(above));     float below = StyleConstants.getSpaceBelow(style);     belowField.setText(Float.toString(below));     boolean bold = StyleConstants.isBold(style);     boldCheck.setSelected(bold);     boolean italic = StyleConstants.isItalic(style);     italicCheck.setSelected(italic);   } }