/** * Copyright (C) 2015 Valkyrie RCP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.valkyriercp.command.support; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.valkyriercp.command.ActionCommandExecutor; import org.valkyriercp.command.ActionCommandInterceptor; import org.valkyriercp.command.config.CommandFaceDescriptor; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; public abstract class ActionCommand extends AbstractCommand implements ActionCommandExecutor, ParameterizableActionCommandExecutor { public static final String ACTION_COMMAND_PROPERTY = "actionCommand"; public static final String ACTION_COMMAND_PARAMETER_KEY = "actionCommand"; public static final String ACTION_EVENT_PARAMETER_KEY = "actionEvent"; public static final String MODIFIERS_PARAMETER_KEY = "modifiers"; private static final String ELLIPSES = "..."; private List<ActionCommandInterceptor> commandInterceptors; private String actionCommand; private SwingActionAdapter swingActionAdapter; private Map<Object, Object> parameters = new HashMap<Object, Object>(6); private boolean displaysInputDialog; public ActionCommand() { super(); } public ActionCommand(String commandId) { super(commandId); } public ActionCommand(String id, CommandFaceDescriptor face) { super(id, face); } public ActionCommand(String id, String encodedLabel) { super(id, encodedLabel); } public ActionCommand(String id, String encodedLabel, Icon icon, String caption) { super(id, encodedLabel, icon, caption); } public void addParameter(Object key, Object value) { parameters.put(key, value); } protected Object getParameter(Object key) { return parameters.get(key); } protected Map getParameters() { return Collections.unmodifiableMap(parameters); } protected Object getParameter(Object key, Object defaultValue) { Object value = parameters.get(key); return value != null ? value : defaultValue; } public void addCommandInterceptor(ActionCommandInterceptor l) { if (commandInterceptors == null) { commandInterceptors = new ArrayList<ActionCommandInterceptor>(6); } commandInterceptors.add(l); } public void removeCommandInterceptor(ActionCommandInterceptor l) { Assert.notNull(commandInterceptors, "The command interceptors list has not yet been initialized"); commandInterceptors.remove(l); } protected void onButtonAttached(AbstractButton button) { super.onButtonAttached(button); button.setActionCommand(actionCommand); button.addActionListener(actionPerformedHandler); if (displaysInputDialog) { if (button.getText() != null && !button.getText().endsWith(ELLIPSES)) { button.setText(getText() + ELLIPSES); } } } ActionListener actionPerformedHandler = new ActionListener() { public void actionPerformed(ActionEvent e) { addParameter(ACTION_EVENT_PARAMETER_KEY, e); addParameter(MODIFIERS_PARAMETER_KEY, e.getModifiers()); addParameter(ACTION_COMMAND_PARAMETER_KEY, ActionCommand.this); execute(); } }; protected int getModifiers() { return (Integer) getParameter(MODIFIERS_PARAMETER_KEY, 0); } public Action getActionAdapter() { if (swingActionAdapter == null) { this.swingActionAdapter = new SwingActionAdapter(this); } return swingActionAdapter; } public String getActionCommand() { return actionCommand; } public void setActionCommand(String newCommandName) { if (!ObjectUtils.nullSafeEquals(actionCommand, newCommandName)) { String old = actionCommand; actionCommand = newCommandName; Iterator iter = buttonIterator(); while (iter.hasNext()) { AbstractButton button = (AbstractButton) iter.next(); button.setActionCommand(actionCommand); } firePropertyChange(ACTION_COMMAND_PROPERTY, old, newCommandName); } } public void setDefaultButtonIn(RootPaneContainer container) { JRootPane rootPane = container.getRootPane(); JButton button = (JButton) getButtonIn(rootPane); if (button != null) { rootPane.setDefaultButton(button); } } public void setDefaultButton() { Iterator it = buttonIterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof JButton) { JButton button = (JButton) o; JRootPane pane = SwingUtilities.getRootPane(button); if (pane != null) { pane.setDefaultButton(button); } } } } public void setDisplaysInputDialog(boolean displaysInputDialog) { this.displaysInputDialog = displaysInputDialog; } public boolean isDisplaysInputDialog() { return displaysInputDialog; } public final void execute(Map parameters) { this.parameters.putAll(parameters); execute(); } public final void execute() { if (onPreExecute()) { doExecuteCommand(); onPostExecute(); } parameters.clear(); } protected final boolean onPreExecute() { if (commandInterceptors == null) { return true; } for (Object commandInterceptor : commandInterceptors) { ActionCommandInterceptor listener = (ActionCommandInterceptor) commandInterceptor; if (!listener.preExecution(this)) { return false; } } return true; } protected abstract void doExecuteCommand(); protected final void onPostExecute() { if (commandInterceptors == null) { return; } for (Object commandInterceptor : commandInterceptors) { ActionCommandInterceptor interceptor = (ActionCommandInterceptor) commandInterceptor; interceptor.postExecution(this); } } /** * Returns <code>true</code> if the shift key was down when invoking this * <code>ActionCommand</code>. * * @return <code>true</code> if the shift key was down, <code>false</code> * otherwise */ protected boolean isShiftDown() { return (getModifiers() & ActionEvent.SHIFT_MASK) != 0; } /** * Returns <code>true</code> if the control key was down when invoking this * <code>ActionCommand</code>. * * @return <code>true</code> if the control key was down, <code>false</code> * otherwise */ protected boolean isControlDown() { return (getModifiers() & ActionEvent.CTRL_MASK) != 0; } /** * Returns <code>true</code> if the meta key was down when invoking this * <code>ActionCommand</code>. * * @return <code>true</code> if the meta key was down, <code>false</code> * otherwise */ protected boolean isMetaDown() { return (getModifiers() & ActionEvent.META_MASK) != 0; } /** * Returns <code>true</code> if the alt key was down when invoking this * <code>ActionCommand</code>. * * @return <code>true</code> if the alt key was down, <code>false</code> * otherwise */ protected boolean isAltDown() { return (getModifiers() & ActionEvent.ALT_MASK) != 0; } }