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