1 19 20 package org.netbeans.modules.enode; 21 22 import java.awt.Component ; 23 import java.util.ArrayList ; 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.Iterator ; 27 import java.util.LinkedList ; 28 import java.util.List ; 29 import java.util.ListIterator ; 30 import javax.swing.*; 31 import javax.swing.JComponent ; 32 import javax.swing.JSeparator ; 33 34 import org.openide.ErrorManager; 35 import org.openide.awt.Actions; 36 import org.openide.util.Lookup; 37 38 import org.netbeans.modules.enode.*; 39 import org.openide.util.ContextAwareAction; 40 41 46 public class SubMenuAction extends AbstractAction implements 47 org.openide.util.actions.Presenter.Popup, 48 org.openide.util.actions.Presenter.Menu, ContextAwareAction { 49 50 private static ErrorManager log = ErrorManager.getDefault().getInstance(SubMenuAction.class.getName()); 51 private static boolean LOGGABLE = log.isLoggable(ErrorManager.INFORMATIONAL); 52 53 54 private String name; 55 56 private Lookup ctx; 57 58 private List entries = new ArrayList (); 59 60 61 private SubMenuCache.MenuEntry currentEntry; 62 63 64 public SubMenuAction() { 65 this("Test"); } 67 68 70 public SubMenuAction(String name) { 71 this(name, null, null, null); 72 } 73 74 76 public SubMenuAction(SubMenuCache.MenuEntry current) { 77 this(current.getDisplayName(), null, current, null); 78 } 79 80 83 private SubMenuAction(String name, Lookup ctx, SubMenuCache.MenuEntry currentEntry, List entries) { 84 this.name = name; 85 this.ctx = ctx; 86 this.currentEntry = currentEntry; 87 if (entries != null) { 88 this.entries = entries; 89 } 90 } 91 92 97 public void actionPerformed(java.awt.event.ActionEvent e) { 98 throw new IllegalStateException ("SubMenuAction should not be performed as action."); } 100 101 104 public Action createContextAwareInstance(Lookup actionContext) { 105 return new SubMenuAction(name, actionContext, currentEntry, entries); 106 } 107 108 111 public JMenuItem getMenuPresenter() { 112 return getPopupPresenter(); 113 } 114 115 118 public JMenuItem getPopupPresenter() { 119 return createMenu(name); 120 } 121 122 125 private JMenuItem createMenu(String name) { 126 ENodePopupSubMenu menu = new ENodePopupSubMenu(name, currentEntry); 127 menu.addAllCacheItems(entries); 128 menu.buildMenu(); 129 return menu; 130 } 131 132 135 public boolean equals(Object another) { 136 if ((another == null) || (! (another instanceof SubMenuAction) ) ){ 137 return false; 138 } 139 SubMenuAction other = (SubMenuAction)another; 140 if (name == null) { 141 return other.name == null; 142 } 143 return name.equals(other.name); 144 } 145 146 149 public int hashCode() { 150 if (name == null) { 151 return 0; 152 } 153 return name.hashCode(); 154 } 155 156 159 public boolean isEmpty() { 160 return entries.isEmpty(); 161 } 162 163 166 public void addItemFromCache(SubMenuCache.CacheEntry entry) { 167 entries.add(entry); 168 } 169 170 public void addAllCacheItems(Collection newEntries) { 171 entries.addAll(newEntries); 172 } 173 174 177 public Collection getCacheItries() { 178 return Collections.unmodifiableList(entries); 179 } 180 181 184 private static CacheEntryWithSubmenuPointer insertEntry( 185 List list, 186 SubMenuCache.CacheEntry entry, 187 SubMenuCache.MenuEntry myMenu) { 188 SubMenuCache.CacheEntry e = entry; 189 while ((e.getParent() != null) && (!e.getParent().equals(myMenu))) { 190 e = e.getParent(); 191 } 192 if (e.getParent() == null) { 193 log.log(entry + " is not under " + myMenu); 194 return null; 195 } 196 197 CacheEntryWithSubmenuPointer fresh = new CacheEntryWithSubmenuPointer(); 198 fresh.topLevel = e; 199 fresh.leaf = entry; 200 CacheEntryWithSubmenuPointer existing = null; 201 ListIterator it = list.listIterator(); 202 while (it.hasNext()) { 203 existing = (CacheEntryWithSubmenuPointer)it.next(); 204 if (! e.getParent().equals(existing.topLevel.getParent())) { 205 throw new IllegalStateException (existing.topLevel + " doesn't have same parent as " + e); 206 } 207 int entryIndex = e.getIndex(); 208 int existingIndex = existing.topLevel.getIndex(); 209 if (entryIndex < existingIndex) { 210 if (it.hasPrevious()) { 211 it.previous(); 212 } 213 it.add(fresh); 214 return fresh; 215 } 216 } 217 it.add(fresh); 219 return fresh; 220 } 221 222 private class ENodePopupSubMenu extends JMenu { 223 private List elements = new LinkedList (); 224 private SubMenuCache.MenuEntry menuEntry; 225 public ENodePopupSubMenu(String name, SubMenuCache.MenuEntry menuEntry) { 226 super(name); 227 this.menuEntry = menuEntry; 228 } 229 232 public void addItemFromCache(SubMenuCache.CacheEntry entry) { 233 CacheEntryWithSubmenuPointer e = insertEntry(elements, entry, menuEntry); 234 } 235 236 public void addAllCacheItems(Collection newEntries) { 237 if (LOGGABLE) log.log("addAllCacheItems on menu" + getText()); 238 for (Iterator it = newEntries.iterator(); it.hasNext();) { 239 SubMenuCache.CacheEntry e = (SubMenuCache.CacheEntry)it.next(); 240 if (LOGGABLE) log.log("addAllCacheItems adding " + e); 241 addItemFromCache(e); 242 } 243 } 244 245 public void buildMenu() { 246 if (LOGGABLE) log.log("buildMenu() " + getText()); 247 for (Iterator it = elements.iterator(); it.hasNext();) { 248 CacheEntryWithSubmenuPointer cewsp = (CacheEntryWithSubmenuPointer)it.next(); 249 if (LOGGABLE) log.log("buildMenu() trying to add: " + cewsp.leaf + " cewsp.topLevel: " + cewsp.topLevel); 250 if (cewsp.leaf.equals(cewsp.topLevel)) { 251 if (cewsp.leaf instanceof SubMenuCache.ActionEntry) { 252 SubMenuCache.ActionEntry actionEntry = (SubMenuCache.ActionEntry)cewsp.leaf; 253 Object obj = actionEntry.getActionObject(); 254 if (obj instanceof Action) { 255 Action a = (Action)obj; 256 if ((ctx != null) && a instanceof ContextAwareAction) { 257 a = ((ContextAwareAction)a).createContextAwareInstance(ctx); 258 } 259 JMenuItem menuItem = new JMenuItem(); 260 Actions.connect(menuItem, a, true); 261 add(menuItem); 262 } 263 if (obj instanceof JSeparator ) { 264 add(new JSeparator ()); 266 } else { 267 if (obj instanceof JComponent ) { 268 add((JComponent )obj); 269 } 270 } 271 } 272 } else { 273 log.log("Adding submenu for " + cewsp.leaf); 274 if (cewsp.topLevel instanceof SubMenuCache.MenuEntry) { 275 SubMenuCache.MenuEntry subMenu = (SubMenuCache.MenuEntry)cewsp.topLevel; 276 String subMenuDisplayName = subMenu.getDisplayName(); 277 ENodePopupSubMenu sub = findSubMenu(subMenuDisplayName); 278 if (sub != null) { 279 sub.addItemFromCache(cewsp.leaf); 280 } else { 281 ENodePopupSubMenu newSub = new ENodePopupSubMenu(subMenu.getDisplayName(), subMenu); 283 newSub.addItemFromCache(cewsp.leaf); 284 add(newSub); 285 } 286 } else { 287 log.log("cewsp.topLevel " + cewsp.topLevel + " is not MenuEntry."); 288 } 289 } 290 } 291 Component [] subMenus = getMenuComponents(); 292 for (int i = 0; i < subMenus.length; i++) { 293 if (subMenus[i] instanceof ENodePopupSubMenu) { 294 ENodePopupSubMenu sub = (ENodePopupSubMenu)subMenus[i]; 295 sub.buildMenu(); 296 } 297 } 298 299 } 300 301 public ENodePopupSubMenu findSubMenu(String displayName) { 302 Component [] subMenus = getMenuComponents(); 303 for (int i = 0; i < subMenus.length; i++) { 304 if (subMenus[i] instanceof ENodePopupSubMenu) { 305 ENodePopupSubMenu sub = (ENodePopupSubMenu)subMenus[i]; 306 if (displayName.equals(sub.getText())) { 307 return sub; 308 } 309 } 310 } 311 return null; 312 } 313 } 314 315 322 private static class CacheEntryWithSubmenuPointer { 323 327 public SubMenuCache.CacheEntry topLevel; 328 public SubMenuCache.CacheEntry leaf; 329 } 330 } 331 | Popular Tags |