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