001 /*
002 * Copyright 2002-2004 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 java.util.Iterator;
019 import java.util.List;
020
021 import javax.swing.AbstractButton;
022 import javax.swing.JMenuItem;
023
024 import org.springframework.core.style.ToStringCreator;
025 import org.springframework.richclient.command.config.CommandButtonConfigurer;
026 import org.springframework.richclient.factory.ButtonFactory;
027 import org.springframework.richclient.factory.MenuFactory;
028 import org.springframework.richclient.util.Assert;
029
030 /**
031 * A simple implementation of the {@link GroupMember} interface that manages normal commands that
032 * can be associated with instances of {@link AbstractButton}s.
033 *
034 */
035 public class SimpleGroupMember extends GroupMember {
036
037 private final CommandGroup parent;
038
039 private final AbstractCommand command;
040
041 /**
042 * Creates a new {@code SimpleGroupMember} belonging to the given command group and wrapping
043 * the given command.
044 *
045 * @param parentGroup The command group that this member belongs to.
046 * @param command The command that this group member represents.
047 *
048 * @throws IllegalArgumentException if either argument is null.
049 * @throws InvalidGroupMemberException if the given command group does not support the type of
050 * the given command.
051 */
052 public SimpleGroupMember(CommandGroup parentGroup, AbstractCommand command) {
053 this.parent = parentGroup;
054 this.command = command;
055
056 if (!parentGroup.isAllowedMember(command)) {
057 throw new InvalidGroupMemberException(command.getClass(), parentGroup.getClass());
058 }
059
060 }
061
062 /**
063 * Sets the enabled flag of the underlying command.
064 */
065 public void setEnabled(boolean enabled) {
066 command.setEnabled(enabled);
067 }
068
069
070 protected void fill(GroupContainerPopulator containerPopulator,
071 Object controlFactory,
072 CommandButtonConfigurer buttonConfigurer,
073 List previousButtons) {
074
075 Assert.required(containerPopulator, "containerPopulator");
076 Assert.required(buttonConfigurer, "buttonConfigurer");
077
078 if (controlFactory instanceof MenuFactory) {
079 JMenuItem menu = findMenu(command, previousButtons);
080
081 if (menu == null) {
082 menu = command.createMenuItem(((MenuFactory)controlFactory), buttonConfigurer);
083 }
084
085 logger.debug("Adding menu item to container");
086 containerPopulator.add(menu);
087 }
088 else if (controlFactory instanceof ButtonFactory) {
089 AbstractButton button = findButton(command, previousButtons);
090
091 if (button == null) {
092 button = command.createButton(((ButtonFactory)controlFactory), buttonConfigurer);
093 }
094
095 logger.debug("Adding button to container");
096 containerPopulator.add(button);
097 }
098
099 }
100
101 /**
102 * {@inheritDoc}
103 */
104 public boolean managesCommand(String commandId) {
105 //FIXME isn't this supposed to recursively check subcommands if command is a commandgroup?
106
107 if (commandId == null) {
108 return false;
109 }
110
111 return commandId.equals(this.command.getId());
112
113 }
114
115 /**
116 * Returns the underlying command, never null.
117 * @return The underlying command.
118 */
119 public AbstractCommand getCommand() {
120 return command;
121 }
122
123 /**
124 * Searches the given list of {@link AbstractButton}s for one that is an instance of a
125 * {@link JMenuItem} and has the given command attached to it. If found, the menu item will be
126 * removed from the list.
127 *
128 * @param attachedCommand The command that we are checking to see if it attached to any item in the list.
129 * @param abstractButtons The collection of {@link AbstractButton}s that will be checked to
130 * see if they have the given command attached to them. May be null or empty.
131 *
132 * @return The element from the list that the given command is attached to, or null if no
133 * such element could be found.
134 *
135 */
136 protected JMenuItem findMenu(AbstractCommand attachedCommand, List abstractButtons) {
137
138 if (abstractButtons == null) {
139 return null;
140 }
141
142 for (Iterator it = abstractButtons.iterator(); it.hasNext();) {
143 AbstractButton button = (AbstractButton)it.next();
144 if (button instanceof JMenuItem && attachedCommand.isAttached(button)) {
145 it.remove();
146 return (JMenuItem)button;
147 }
148 }
149 return null;
150 }
151
152 /**
153 * Searches the given list of {@link AbstractButton}s for one that is not an instance of a
154 * {@link JMenuItem} and has the given command attached to it. If found, the button will be
155 * removed from the list.
156 *
157 * @param attachedCommand The command that we are checking to see if it attached to any item in the list.
158 * @param abstractButtons The collection of {@link AbstractButton}s that will be checked to
159 * see if they have the given command attached to them. May be null or empty.
160 *
161 * @return The element from the list that the given command is attached to, or null if no
162 * such element could be found.
163 *
164 */
165 protected AbstractButton findButton(AbstractCommand attachedCommand, List buttons) {
166
167 if (buttons == null) {
168 return null;
169 }
170
171 for (Iterator it = buttons.iterator(); it.hasNext();) {
172 AbstractButton button = (AbstractButton)it.next();
173 if (!(button instanceof JMenuItem) && attachedCommand.isAttached(button)) {
174 it.remove();
175 return button;
176 }
177 }
178 return null;
179 }
180
181 /**
182 * {@inheritDoc}
183 */
184 protected void onAdded() {
185 if (parent instanceof ExclusiveCommandGroup) {
186 ((ExclusiveCommandGroup)parent).getSelectionController().add((ToggleCommand)command);
187 }
188 }
189
190 /**
191 * {@inheritDoc}
192 */
193 protected void onRemoved() {
194 if (parent instanceof ExclusiveCommandGroup) {
195 ((ExclusiveCommandGroup)parent).getSelectionController().remove((ToggleCommand)command);
196 }
197 }
198
199 /**
200 * {@inheritDoc}
201 */
202 public String toString() {
203 return new ToStringCreator(this).append("command", command).toString();
204 }
205
206 }