001 /*
002 * Copyright 2008-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of 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,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.codehaus.griffon.runtime.swing.controller;
017
018 import griffon.core.RunnableWithArgs;
019 import griffon.core.artifact.GriffonController;
020 import griffon.core.controller.ActionManager;
021 import griffon.core.editors.PropertyEditorResolver;
022 import griffon.core.threading.UIThreadManager;
023 import griffon.swing.support.SwingAction;
024 import org.codehaus.griffon.runtime.core.controller.AbstractAction;
025
026 import javax.annotation.Nonnull;
027 import javax.annotation.Nullable;
028 import javax.swing.Action;
029 import javax.swing.Icon;
030 import javax.swing.KeyStroke;
031 import java.awt.event.ActionEvent;
032 import java.beans.PropertyChangeEvent;
033 import java.beans.PropertyChangeListener;
034 import java.beans.PropertyEditor;
035
036 import static griffon.util.GriffonNameUtils.isBlank;
037 import static java.util.Objects.requireNonNull;
038
039 /**
040 * @author Andres Almiray
041 * @since 2.0.0
042 */
043 public class SwingGriffonControllerAction extends AbstractAction {
044 public static final String KEY_SHORT_DESCRIPTION = "shortDescription";
045 public static final String KEY_LONG_DESCRIPTION = "longDescription";
046 public static final String KEY_SMALL_ICON = "smallIcon";
047 public static final String KEY_LARGE_ICON = "largeIcon";
048 public static final String KEY_SELECTED = "selected";
049 public static final String KEY_ACCELERATOR = "accelerator";
050 public static final String KEY_MNEMONIC = "mnemonic";
051 public static final String KEY_COMMAND = "command";
052 private final SwingAction toolkitAction;
053 private String shortDescription;
054 private String longDescription;
055 private String smallIcon;
056 private String largeIcon;
057 private String accelerator;
058 private String mnemonic;
059 private String command;
060 private boolean selected;
061
062 public SwingGriffonControllerAction(final @Nonnull UIThreadManager uiThreadManager, @Nonnull final ActionManager actionManager, @Nonnull final GriffonController controller, @Nonnull final String actionName) {
063 super(actionManager, controller, actionName);
064 requireNonNull(uiThreadManager, "Argument 'uiThreadManager' must not be null");
065
066 toolkitAction = createAction(actionManager, controller, actionName);
067
068 addPropertyChangeListener(new PropertyChangeListener() {
069 public void propertyChange(final PropertyChangeEvent evt) {
070 uiThreadManager.runInsideUIAsync(new Runnable() {
071 public void run() {
072 handlePropertyChange(evt);
073 }
074 });
075 }
076 });
077 }
078
079 @Nonnull
080 protected SwingAction createAction(final @Nonnull ActionManager actionManager, final @Nonnull GriffonController controller, final @Nonnull String actionName) {
081 return new SwingAction(new RunnableWithArgs() {
082 public void run(@Nullable Object... args) {
083 actionManager.invokeAction(controller, actionName, args);
084 }
085 });
086 }
087
088 protected void handlePropertyChange(@Nonnull PropertyChangeEvent evt) {
089 if (KEY_NAME.equals(evt.getPropertyName())) {
090 toolkitAction.putValue(Action.NAME, evt.getNewValue());
091 } else if (KEY_COMMAND.equals(evt.getPropertyName())) {
092 toolkitAction.putValue(Action.ACTION_COMMAND_KEY, evt.getNewValue());
093 } else if (KEY_SHORT_DESCRIPTION.equals(evt.getPropertyName())) {
094 toolkitAction.putValue(Action.SHORT_DESCRIPTION, evt.getNewValue());
095 } else if (KEY_LONG_DESCRIPTION.equals(evt.getPropertyName())) {
096 toolkitAction.putValue(Action.LONG_DESCRIPTION, evt.getNewValue());
097 } else if (KEY_ENABLED.equals(evt.getPropertyName())) {
098 toolkitAction.setEnabled((Boolean) evt.getNewValue());
099 } else if (KEY_SELECTED.equals(evt.getPropertyName())) {
100 toolkitAction.putValue(Action.SELECTED_KEY, evt.getNewValue());
101 } else if (KEY_MNEMONIC.equals(evt.getPropertyName())) {
102 String mnemonic = (String) evt.getNewValue();
103 if (!isBlank(mnemonic)) {
104 toolkitAction.putValue(Action.MNEMONIC_KEY, KeyStroke.getKeyStroke(mnemonic).getKeyCode());
105 }
106 } else if (KEY_ACCELERATOR.equals(evt.getPropertyName())) {
107 String accelerator = (String) evt.getNewValue();
108 if (!isBlank(accelerator)) {
109 toolkitAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accelerator));
110 }
111 } else if (KEY_SMALL_ICON.equals(evt.getPropertyName())) {
112 handleIcon(evt.getNewValue(), Action.SMALL_ICON);
113 } else if (KEY_LARGE_ICON.equals(evt.getPropertyName())) {
114 handleIcon(evt.getNewValue(), Action.LARGE_ICON_KEY);
115 }
116 }
117
118 protected void handleIcon(@Nullable Object value, @Nonnull String key) {
119 if (value != null) {
120 PropertyEditor editor = PropertyEditorResolver.findEditor(Icon.class);
121 editor.setValue(value);
122 toolkitAction.putValue(key, editor.getValue());
123 }
124 }
125
126 protected void doInitialize() {
127 toolkitAction.putValue(Action.NAME, getName());
128 toolkitAction.putValue(Action.ACTION_COMMAND_KEY, getCommand());
129 toolkitAction.putValue(Action.SHORT_DESCRIPTION, getShortDescription());
130 toolkitAction.putValue(Action.LONG_DESCRIPTION, getLongDescription());
131 toolkitAction.setEnabled(isEnabled());
132 toolkitAction.putValue(Action.SELECTED_KEY, isSelected());
133 String mnemonic = getMnemonic();
134 if (!isBlank(mnemonic)) {
135 toolkitAction.putValue(Action.MNEMONIC_KEY, KeyStroke.getKeyStroke(mnemonic).getKeyCode());
136 }
137 String accelerator = getAccelerator();
138 if (!isBlank(accelerator)) {
139 toolkitAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accelerator));
140 }
141 handleIcon(getSmallIcon(), Action.SMALL_ICON);
142 handleIcon(getLargeIcon(), Action.LARGE_ICON_KEY);
143 }
144
145 @Nullable
146 public String getAccelerator() {
147 return accelerator;
148 }
149
150 public void setAccelerator(@Nullable String accelerator) {
151 firePropertyChange(KEY_ACCELERATOR, this.accelerator, this.accelerator = accelerator);
152 }
153
154 @Nullable
155 public String getLargeIcon() {
156 return largeIcon;
157 }
158
159 public void setLargeIcon(@Nullable String largeIcon) {
160 firePropertyChange(KEY_LARGE_ICON, this.largeIcon, this.largeIcon = largeIcon);
161 }
162
163 @Nullable
164 public String getLongDescription() {
165 return longDescription;
166 }
167
168 public void setLongDescription(@Nullable String longDescription) {
169 firePropertyChange(KEY_LONG_DESCRIPTION, this.longDescription, this.longDescription = longDescription);
170 }
171
172 @Nullable
173 public String getMnemonic() {
174 return mnemonic;
175 }
176
177 public void setMnemonic(@Nullable String mnemonic) {
178 firePropertyChange(KEY_MNEMONIC, this.mnemonic, this.mnemonic = mnemonic);
179 }
180
181 public boolean isSelected() {
182 return selected;
183 }
184
185 public void setSelected(boolean selected) {
186 firePropertyChange(KEY_SELECTED, this.selected, this.selected = selected);
187 }
188
189 @Nullable
190 public String getShortDescription() {
191 return shortDescription;
192 }
193
194 public void setShortDescription(@Nullable String shortDescription) {
195 firePropertyChange(KEY_SHORT_DESCRIPTION, this.shortDescription, this.shortDescription = shortDescription);
196 }
197
198 @Nullable
199 public String getSmallIcon() {
200 return smallIcon;
201 }
202
203 public void setSmallIcon(@Nullable String smallIcon) {
204 firePropertyChange(KEY_SMALL_ICON, this.smallIcon, this.smallIcon = smallIcon);
205 }
206
207 @Nullable
208 public String getCommand() {
209 return command;
210 }
211
212 public void setCommand(@Nullable String command) {
213 firePropertyChange(KEY_SMALL_ICON, this.command, this.command = command);
214 }
215
216 @Nonnull
217 public Object getToolkitAction() {
218 return toolkitAction;
219 }
220
221 protected void doExecute(Object... args) {
222 ActionEvent event = null;
223 if (args != null && args.length == 1 && args[0] instanceof ActionEvent) {
224 event = (ActionEvent) args[0];
225 }
226 toolkitAction.actionPerformed(event);
227 }
228 }
|