View Javadoc

1   /*
2    *  XNap Commons
3    *
4    *  Copyright (C) 2005  Felix Berger
5    *  Copyright (C) 2005  Steffen Pingel
6    *
7    *  This library is free software; you can redistribute it and/or
8    *  modify it under the terms of the GNU Lesser General Public
9    *  License as published by the Free Software Foundation; either
10   *  version 2.1 of the License, or (at your option) any later version.
11   *
12   *  This library is distributed in the hope that it will be useful,
13   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   *  Lesser General Public License for more details.
16   *
17   *  You should have received a copy of the GNU Lesser General Public
18   *  License along with this library; if not, write to the Free Software
19   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   */
21  package org.xnap.commons.gui.shortcut;
22  
23  import java.util.Iterator;
24  import java.util.LinkedList;
25  import javax.swing.Action;
26  import javax.swing.InputMap;
27  import javax.swing.JComponent;
28  import javax.swing.JMenuItem;
29  import javax.swing.KeyStroke;
30  
31  /***
32   * Provides an action based shortcut.
33   * 
34   * <p>The action has to provide several values to make use of the shortcut.</p>
35   * 
36   * <p>It must provide the following values:</p>
37   * 
38   * <p>Action.ACTION_COMMAND_KEY, the preferences key</p>
39   *
40   * <p>It should provide values for the following keys:</p>
41   * 
42   * <pre>
43   * </pre>
44   */
45  public class ActionShortcut extends AbstractShortcut
46  {
47  
48  	private Action action;
49  
50  	private LinkedList<JComponent> components = new LinkedList<JComponent>();
51  	private JMenuItem menuItem;
52  	
53      public ActionShortcut(Action action, JComponent c) 
54      {
55      	this.action = action;
56  		addComponent(c, action);
57      }   
58  
59  	public ActionShortcut(Action action) 
60  	{
61  		if (action == null) {
62  			throw new NullPointerException("action must not be null");
63  		}
64  		this.action = action;
65  	}
66  	
67  	/***
68  	 * Installs the action into the action map of the component and sets up
69  	 * the shortcut mapping.  
70  	 */
71  	public void addComponent(JComponent c, Action a)
72  	{
73  		// install action into action map
74  		c.getActionMap().put(this, a);
75  		components.add(c);
76  		setKeyStroke(getKeyStroke(), c);
77  	}
78  
79  	public JMenuItem getMenuItem()
80  	{
81  		return menuItem;
82  	}
83  
84  	public Action getAction()
85  	{
86  		return action;
87  	}
88  	
89  	public void setMenuItem(JMenuItem menuItem)
90  	{
91  		if (this.menuItem != null) {
92  			this.menuItem.setAccelerator(null);
93  		}
94  		this.menuItem = menuItem;
95  		if (this.menuItem != null) {
96  			this.menuItem.setAccelerator(getKeyStroke());
97  		}
98  	}
99  
100 	/***
101 	 * Removes the action mapping from the given component and removes it
102 	 * from its list of components.
103 	 * @param c the component this shortcuts is registered on
104 	 */
105 	public void removeComponent(JComponent c)
106 	{
107 		// remove action from action map
108 		c.getActionMap().remove(this);
109 		components.remove(c);
110 	}
111 
112 	/***
113 	 * Returns the number of components this shortcut is registered upon.
114 	 */
115 	public int getNumberOfComponents()
116 	{
117 		return components.size();
118 	}
119 
120 	private void setKeyStroke(KeyStroke stroke, JComponent c)
121 	{
122 		InputMap m = c.getInputMap
123 			(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
124 
125 		// remove old mapping
126 		if (getKeyStroke() != null) {
127 			m.remove(getKeyStroke());
128 		}
129 		// install new mapping
130 		if (stroke != null) {
131 			m.put(stroke, this);
132 		}
133 	}
134 
135     public void setKeyStroke(KeyStroke stroke) 
136     {
137 		for (Iterator<JComponent> i = components.iterator(); i.hasNext();) {
138 			setKeyStroke(stroke, i.next());
139 		}
140 		if (menuItem != null) {
141 			menuItem.setAccelerator(stroke);
142 		}
143 		super.setKeyStroke(stroke);
144     }
145 }
146