package misc; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.List; import java.util.Vector; import javax.swing.AbstractButton; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; public class StoryManager implements ApplicationManager, ActionListener { // ======================================== static public final String actionUndo = "Undo", actionRedo = "Redo"; static public final List actionsNames = Arrays.asList (actionUndo, actionRedo); @SuppressWarnings("unchecked") static public final Hashtable actionsMethod = Util.collectMethod (StoryManager.class, actionsNames); public void actionPerformed (ActionEvent e) { Util.actionPerformed (actionsMethod, e, this); } private ArrayList enabledUndoButtons = new ArrayList (); private ArrayList enabledRedoButtons = new ArrayList (); // ======================================== public void addMenuItem (JMenu... jMenu) { Util.addMenuItem (actionsNames, this, jMenu[0]); } public void addIconButtons (Container... containers) { addListButton (Util.addIconButton (actionUndo, this, containers[0]), true); addListButton (Util.addIconButton (actionRedo, this, containers[0]), false); } public void addListButton (JButton button, boolean undo) { Dimension currentSize = button.getPreferredSize (); button.setLayout (new BorderLayout ()); JLabel develop = new JLabel (Util.loadActionIcon ("develop")); Dimension addedSize = develop.getPreferredSize (); button.add (develop, BorderLayout.EAST); currentSize.width += addedSize.width; button.setPreferredSize (currentSize); develop.addMouseListener (new MouseAdapter () { public void mousePressed (MouseEvent e) { button.setSelected (false); if (!button.isEnabled () || story == null) return; new JStoryPopup (button, undo, SwingUtilities.convertMouseEvent (develop, e, button).getPoint ()); } }); } @SuppressWarnings ("serial") class JStoryPopup extends JPopupMenu { public JStoryPopup (JButton button, boolean undo, Point pos) { Vector cmds = undo ? story.getUndoCmd () : story.getRedoCmd (); for (int i = 0; i < cmds.size (); i++) { if (i >= 10) { add (new JLabel ("...")); break; } JMenuItem jMenu = new JMenuItem (Bundle.getStory (cmds.get (i))); final int count = i+1; jMenu.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent e) { if (undo) story.undo (count); else story.redo (count); } }); add (jMenu); } show (button, pos.x, pos.y); } } public void addActiveButtons (Hashtable buttons) { enabledUndoButtons.add (buttons.get (actionUndo)); enabledRedoButtons.add (buttons.get (actionRedo)); updateActiveButtons (); } public void updateActiveButtons () { updateStory (); } public void updateStory () { boolean undo = false, redo = false; if (story != null) { undo = story.undoAvailable (); redo = story.redoAvailable (); } for (AbstractButton button : enabledUndoButtons) button.setEnabled (undo); for (AbstractButton button : enabledRedoButtons) button.setEnabled (redo); } public void actionUndo () { if (story == null) return; story.undo (1); } public void actionRedo () { if (story == null) return; story.redo (1); } // ======================================== Story story; public void setStory (Story story) { if (this.story != null) this.story.removeObserver (this); this.story = story; if (story != null) story.addUpdateObserver (this); updateStory (); } // public StoryManager () { // } // ======================================== }