001 /* 002 * Copyright 2002-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.richclient.command; 017 018 import org.springframework.richclient.command.config.CommandFaceDescriptor; 019 import org.springframework.util.Assert; 020 import org.springframework.util.ObjectUtils; 021 022 import javax.swing.*; 023 import java.awt.event.ActionEvent; 024 import java.awt.event.ActionListener; 025 import java.util.*; 026 027 public abstract class ActionCommand extends AbstractCommand implements ActionCommandExecutor, 028 ParameterizableActionCommandExecutor 029 { 030 public static final String ACTION_COMMAND_PROPERTY = "actionCommand"; 031 032 public static final String ACTION_COMMAND_PARAMETER_KEY = "actionCommand"; 033 034 public static final String ACTION_EVENT_PARAMETER_KEY = "actionEvent"; 035 036 public static final String MODIFIERS_PARAMETER_KEY = "modifiers"; 037 038 private static final String ELLIPSES = "..."; 039 040 private List<ActionCommandInterceptor> commandInterceptors; 041 042 private String actionCommand; 043 044 private SwingActionAdapter swingActionAdapter; 045 046 private Map<Object, Object> parameters = new HashMap<Object, Object>(6); 047 048 private boolean displaysInputDialog; 049 050 public ActionCommand() 051 { 052 super(); 053 } 054 055 public ActionCommand(String commandId) 056 { 057 super(commandId); 058 } 059 060 public ActionCommand(String id, CommandFaceDescriptor face) 061 { 062 super(id, face); 063 } 064 065 public ActionCommand(String id, String encodedLabel) 066 { 067 super(id, encodedLabel); 068 } 069 070 public ActionCommand(String id, String encodedLabel, Icon icon, String caption) 071 { 072 super(id, encodedLabel, icon, caption); 073 } 074 075 public void addParameter(Object key, Object value) 076 { 077 parameters.put(key, value); 078 } 079 080 protected Object getParameter(Object key) 081 { 082 return parameters.get(key); 083 } 084 085 protected Map getParameters() 086 { 087 return Collections.unmodifiableMap(parameters); 088 } 089 090 protected Object getParameter(Object key, Object defaultValue) 091 { 092 Object value = parameters.get(key); 093 return value != null ? value : defaultValue; 094 } 095 096 public void addCommandInterceptor(ActionCommandInterceptor l) 097 { 098 if (commandInterceptors == null) 099 { 100 commandInterceptors = new ArrayList<ActionCommandInterceptor>(6); 101 } 102 commandInterceptors.add(l); 103 } 104 105 public void removeCommandInterceptor(ActionCommandInterceptor l) 106 { 107 Assert.notNull(commandInterceptors, "The command interceptors list has not yet been initialized"); 108 commandInterceptors.remove(l); 109 } 110 111 protected void onButtonAttached(AbstractButton button) 112 { 113 super.onButtonAttached(button); 114 button.setActionCommand(actionCommand); 115 button.addActionListener(actionPerformedHandler); 116 if (displaysInputDialog) 117 { 118 if (button.getText() != null && !button.getText().endsWith(ELLIPSES)) 119 { 120 button.setText(getText() + ELLIPSES); 121 } 122 } 123 } 124 125 ActionListener actionPerformedHandler = new ActionListener() 126 { 127 public void actionPerformed(ActionEvent e) 128 { 129 addParameter(ACTION_EVENT_PARAMETER_KEY, e); 130 addParameter(MODIFIERS_PARAMETER_KEY, e.getModifiers()); 131 addParameter(ACTION_COMMAND_PARAMETER_KEY, ActionCommand.this); 132 execute(); 133 } 134 }; 135 136 protected int getModifiers() 137 { 138 return (Integer) getParameter(MODIFIERS_PARAMETER_KEY, 0); 139 } 140 141 public Action getActionAdapter() 142 { 143 if (swingActionAdapter == null) 144 { 145 this.swingActionAdapter = new SwingActionAdapter(this); 146 } 147 return swingActionAdapter; 148 } 149 150 public String getActionCommand() 151 { 152 return actionCommand; 153 } 154 155 public void setActionCommand(String newCommandName) 156 { 157 if (!ObjectUtils.nullSafeEquals(actionCommand, newCommandName)) 158 { 159 String old = actionCommand; 160 actionCommand = newCommandName; 161 Iterator iter = buttonIterator(); 162 while (iter.hasNext()) 163 { 164 AbstractButton button = (AbstractButton) iter.next(); 165 button.setActionCommand(actionCommand); 166 } 167 firePropertyChange(ACTION_COMMAND_PROPERTY, old, newCommandName); 168 } 169 } 170 171 public void setDefaultButtonIn(RootPaneContainer container) 172 { 173 JRootPane rootPane = container.getRootPane(); 174 JButton button = (JButton) getButtonIn(rootPane); 175 if (button != null) 176 { 177 rootPane.setDefaultButton(button); 178 } 179 } 180 181 public void setDefaultButton() 182 { 183 Iterator it = buttonIterator(); 184 while (it.hasNext()) 185 { 186 Object o = it.next(); 187 if (o instanceof JButton) 188 { 189 JButton button = (JButton) o; 190 JRootPane pane = SwingUtilities.getRootPane(button); 191 if (pane != null) 192 { 193 pane.setDefaultButton(button); 194 } 195 } 196 } 197 } 198 199 public void setDisplaysInputDialog(boolean displaysInputDialog) 200 { 201 this.displaysInputDialog = displaysInputDialog; 202 } 203 204 public boolean isDisplaysInputDialog() 205 { 206 return displaysInputDialog; 207 } 208 209 public final void execute(Map parameters) 210 { 211 this.parameters.putAll(parameters); 212 execute(); 213 } 214 215 public final void execute() 216 { 217 if (onPreExecute()) 218 { 219 doExecuteCommand(); 220 onPostExecute(); 221 } 222 parameters.clear(); 223 } 224 225 protected final boolean onPreExecute() 226 { 227 if (commandInterceptors == null) 228 { 229 return true; 230 } 231 for (Object commandInterceptor : commandInterceptors) 232 { 233 ActionCommandInterceptor listener = (ActionCommandInterceptor) commandInterceptor; 234 if (!listener.preExecution(this)) 235 { 236 return false; 237 } 238 } 239 return true; 240 } 241 242 protected abstract void doExecuteCommand(); 243 244 protected final void onPostExecute() 245 { 246 if (commandInterceptors == null) 247 { 248 return; 249 } 250 for (Object commandInterceptor : commandInterceptors) 251 { 252 ActionCommandInterceptor interceptor = (ActionCommandInterceptor) commandInterceptor; 253 interceptor.postExecution(this); 254 } 255 } 256 257 /** 258 * Returns <code>true</code> if the shift key was down when invoking this 259 * <code>ActionCommand</code>. 260 * 261 * @return <code>true</code> if the shift key was down, <code>false</code> 262 * otherwise 263 */ 264 protected boolean isShiftDown() 265 { 266 return (getModifiers() & ActionEvent.SHIFT_MASK) != 0; 267 } 268 269 /** 270 * Returns <code>true</code> if the control key was down when invoking this 271 * <code>ActionCommand</code>. 272 * 273 * @return <code>true</code> if the control key was down, <code>false</code> 274 * otherwise 275 */ 276 protected boolean isControlDown() 277 { 278 return (getModifiers() & ActionEvent.CTRL_MASK) != 0; 279 } 280 281 /** 282 * Returns <code>true</code> if the meta key was down when invoking this 283 * <code>ActionCommand</code>. 284 * 285 * @return <code>true</code> if the meta key was down, <code>false</code> 286 * otherwise 287 */ 288 protected boolean isMetaDown() 289 { 290 return (getModifiers() & ActionEvent.META_MASK) != 0; 291 } 292 293 /** 294 * Returns <code>true</code> if the alt key was down when invoking this 295 * <code>ActionCommand</code>. 296 * 297 * @return <code>true</code> if the alt key was down, <code>false</code> 298 * otherwise 299 */ 300 301 protected boolean isAltDown() 302 { 303 return (getModifiers() & ActionEvent.ALT_MASK) != 0; 304 } 305 306 }