package com.towel.awt; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.AbstractButton; /** * Manager that maps an {@link ActionListener} to a button. * * @author Marcos A. Vasconcelos Junior */ public class ActionListenerManager implements ActionListener { private List<ActionListener> before, after; private Map<AbstractButton, ActionListener> map; /** * Creates a new <code>ActionListenerManager</code>. */ public ActionListenerManager() { map = new HashMap<AbstractButton, ActionListener>(); before = new ArrayList<ActionListener>(); after = new ArrayList<ActionListener>(); } /** * Associates a button with an <code>ActionListener</code>, that will have * its {@link ActionListener#actionPerformed(ActionEvent) actionPerformed} * method called when the button has been pressed. * * @param source * the button * @param action * the listener that will be called */ public void manage(AbstractButton source, ActionListener action) { map.put(source, action); source.addActionListener(this); } /** * Adds a new <code>ActionListener</code> that will be called when any * mapped button is pressed. That <code>ActionListener</code>s will be * called before the specific button's action. * * The <code>ActionListener</code>s registered with this method are called * even if the specific button <code>ActionListener</code> fails to execute. * * @param action * the <code>ActionListener</code> that will be called */ public void doBefore(ActionListener action) { before.add(action); } /** * Adds a new <code>ActionListener</code> that will be called when any * mapped button is pressed. That <code>ActionListener</code>s will be * called after the specific button's action. * * The <code>ActionListener</code>s registered with this method are called * even if the specific button <code>ActionListener</code> fails to execute. * * @param action * the <code>ActionListener</code> that will be called */ public void doAfter(ActionListener action) { after.add(action); } @Override public void actionPerformed(ActionEvent arg0) { for (ActionListener action : before) { action.actionPerformed(arg0); } try { map.get(arg0.getSource()).actionPerformed(arg0); } catch (StopException e) { e.getCause().printStackTrace(); } for (ActionListener act : after) { act.actionPerformed(arg0); } } /** * Exception to encapsulate checked exceptions when implementing method * {@link Action#doAction()}. * * @author Marcos A. Vasconcelos Junior */ @SuppressWarnings("serial") public static class StopException extends RuntimeException { /** * The real cause of this exception. */ public Exception cause; /** * Creates a new unchecked exception that encapsulates the given * exception. * * @param cause * the real cause */ public StopException(Exception cause) { this.cause = cause; } @Override public Exception getCause() { return cause; } } }