| 1 | // Copyright 2004-2007 Jean-Francois Poilpret |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package net.sourceforge.hivegui.menu; |
| 16 | |
| 17 | import java.util.Comparator; |
| 18 | import java.util.HashMap; |
| 19 | import java.util.List; |
| 20 | import java.util.Map; |
| 21 | import java.util.SortedSet; |
| 22 | import java.util.TreeSet; |
| 23 | |
| 24 | import javax.swing.Action; |
| 25 | import javax.swing.JMenu; |
| 26 | import javax.swing.JMenuBar; |
| 27 | import javax.swing.JMenuItem; |
| 28 | import javax.swing.JPopupMenu; |
| 29 | |
| 30 | import org.apache.commons.logging.Log; |
| 31 | import org.jdesktop.application.ApplicationContext; |
| 32 | |
| 33 | import net.sourceforge.hivegui.application.ApplicationContextHolder; |
| 34 | |
| 35 | public class MenuFactoryImpl implements MenuFactory |
| 36 | { |
| 37 | public MenuFactoryImpl( Log logger, |
| 38 | List config, |
| 39 | ApplicationContextHolder holder, |
| 40 | MenuInitializer initializer) |
| 41 | { |
| 42 | _logger = logger; |
| 43 | _context = holder.getContext(); |
| 44 | init(config, initializer); |
| 45 | } |
| 46 | |
| 47 | private void init(List config, MenuInitializer initializer) |
| 48 | { |
| 49 | _menuBar.setName("main-menu"); |
| 50 | // Read configuration |
| 51 | SortedSet<MenuContribution> menus = |
| 52 | new TreeSet<MenuContribution>(new ContribComparator()); |
| 53 | Map<String, MenuItemContribution> items = new HashMap<String, MenuItemContribution>(); |
| 54 | for (Object contrib: config) |
| 55 | { |
| 56 | if (contrib instanceof MenuContribution) |
| 57 | { |
| 58 | menus.add((MenuContribution) contrib); |
| 59 | } |
| 60 | else if (contrib instanceof MenuItemContribution) |
| 61 | { |
| 62 | MenuItemContribution itemContrib = (MenuItemContribution) contrib; |
| 63 | items.put(itemContrib.getId(), itemContrib); |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | for (MenuContribution contrib: menus) |
| 68 | { |
| 69 | // Popup menu or not? |
| 70 | if (contrib.isPopup()) |
| 71 | { |
| 72 | initPopup(contrib, items, initializer); |
| 73 | } |
| 74 | else |
| 75 | { |
| 76 | initMenu(contrib, items, initializer); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | initializer.finishInitialization(this); |
| 81 | } |
| 82 | |
| 83 | private void initPopup( MenuContribution contrib, |
| 84 | Map<String, MenuItemContribution> items, |
| 85 | MenuInitializer initializer) |
| 86 | { |
| 87 | JPopupMenu popup = new JPopupMenu(); |
| 88 | String idMenu = contrib.getId(); |
| 89 | popup.setName("popup-" + idMenu); |
| 90 | // For each menu item |
| 91 | String[] idItems = contrib.getItems(); |
| 92 | for (int i = 0; i < idItems.length; i++) |
| 93 | { |
| 94 | // Create item and add to menu |
| 95 | if (idItems[i] == null) |
| 96 | { |
| 97 | popup.addSeparator(); |
| 98 | } |
| 99 | else |
| 100 | { |
| 101 | popup.add(createItem(initializer, items, idItems[i])); |
| 102 | } |
| 103 | } |
| 104 | _popups.put(idMenu, popup); |
| 105 | _context.getResourceMap().injectComponents(popup); |
| 106 | } |
| 107 | |
| 108 | private void initMenu( MenuContribution contrib, |
| 109 | Map<String, MenuItemContribution> items, |
| 110 | MenuInitializer initializer) |
| 111 | { |
| 112 | // Create menu and add to menu bar |
| 113 | JMenu menu = new JMenu(); |
| 114 | menu.setName("menu-" + contrib.getId()); |
| 115 | _menuBar.add(menu); |
| 116 | // For each menu item |
| 117 | String[] idItems = contrib.getItems(); |
| 118 | for (int i = 0; i < idItems.length; i++) |
| 119 | { |
| 120 | // Create item and add to menu |
| 121 | if (idItems[i] == null) |
| 122 | { |
| 123 | menu.addSeparator(); |
| 124 | } |
| 125 | else |
| 126 | { |
| 127 | menu.add(createItem(initializer, items, idItems[i])); |
| 128 | } |
| 129 | } |
| 130 | _context.getResourceMap().injectComponents(menu); |
| 131 | } |
| 132 | |
| 133 | private JMenuItem createItem( MenuInitializer initializer, |
| 134 | Map<String, MenuItemContribution> items, |
| 135 | String idItem) |
| 136 | { |
| 137 | MenuItemContribution contrib = items.get(idItem); |
| 138 | // Create command (ask some help from initializer) |
| 139 | Action command = contrib.getCommand(); |
| 140 | _logger.debug("createItem() id=" + idItem + " command=" + command); |
| 141 | initializer.initAction(idItem, command); |
| 142 | _commands.put(idItem, command); |
| 143 | |
| 144 | // Create a new menu item (NB: can be menu if it can have sub menus) |
| 145 | JMenuItem item; |
| 146 | if (contrib.getHasSubMenus()) |
| 147 | { |
| 148 | item = new JMenu(); |
| 149 | } |
| 150 | else |
| 151 | { |
| 152 | item = new JMenuItem(); |
| 153 | } |
| 154 | |
| 155 | // We use the ActionCommand property to store the id of that item |
| 156 | item.setName("menu-item-" + idItem); |
| 157 | item.setAction(command); |
| 158 | item.setActionCommand(idItem); |
| 159 | return item; |
| 160 | } |
| 161 | |
| 162 | public JMenuBar getMenuBar() |
| 163 | { |
| 164 | return _menuBar; |
| 165 | } |
| 166 | |
| 167 | public JPopupMenu getPopupMenu(String idMenu) |
| 168 | { |
| 169 | return _popups.get(idMenu); |
| 170 | } |
| 171 | |
| 172 | public Action getItemCommand(String idItem) |
| 173 | { |
| 174 | return _commands.get(idItem); |
| 175 | } |
| 176 | |
| 177 | static private class ContribComparator implements Comparator<MenuContribution> |
| 178 | { |
| 179 | public int compare(MenuContribution c1, MenuContribution c2) |
| 180 | { |
| 181 | int diff = c1.getOrder() - c2.getOrder(); |
| 182 | if (diff != 0) |
| 183 | { |
| 184 | return diff; |
| 185 | } |
| 186 | return c1.getId().compareTo(c2.getId()); |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | private final Log _logger; |
| 191 | private final ApplicationContext _context; |
| 192 | private final Map<String, JPopupMenu> _popups = new HashMap<String, JPopupMenu>(); |
| 193 | private final Map<String, Action> _commands = new HashMap<String, Action>(); |
| 194 | private final JMenuBar _menuBar = new JMenuBar(); |
| 195 | } |