1 19 package org.openide.actions; 20 21 import org.openide.awt.Actions; 22 import org.openide.util.ContextAwareAction; 23 import org.openide.util.HelpCtx; 24 import org.openide.util.Lookup; 25 import org.openide.util.NbBundle; 26 import org.openide.util.actions.*; 27 28 import java.beans.*; 29 30 import java.util.*; 31 32 import javax.swing.*; 33 import javax.swing.event.*; 34 import org.openide.awt.DynamicMenuContent; 35 36 37 52 public class ToolsAction extends SystemAction implements ContextAwareAction, Presenter.Menu, Presenter.Popup { 53 static final long serialVersionUID = 4906417339959070129L; 54 55 private static G gl; 58 59 61 private static synchronized G gl() { 62 if (gl == null) { 63 gl = new G(); 64 } 65 66 return gl; 67 } 68 69 71 public String getName() { 72 return getActionName(); 73 } 74 75 77 public HelpCtx getHelpCtx() { 78 return new HelpCtx(ToolsAction.class); 79 } 80 81 83 public JMenuItem getMenuPresenter() { 84 return new Inline(this); 85 } 86 87 89 public JMenuItem getPopupPresenter() { 90 return new Popup(this); 91 } 92 93 95 public void actionPerformed(java.awt.event.ActionEvent ev) { 96 assert false; 97 } 98 99 public Action createContextAwareInstance(Lookup actionContext) { 100 return new DelegateAction(this, actionContext); 101 } 102 103 105 private static String getActionName() { 106 return NbBundle.getMessage(ToolsAction.class, "CTL_Tools"); 107 } 108 109 115 private static List generate(Action toolsAction, boolean forMenu) { 116 ActionManager am = ActionManager.getDefault(); 117 SystemAction[] actions = am.getContextActions(); 118 List list = new ArrayList(actions.length); 119 120 boolean separator = false; 121 boolean firstItemAdded = false; 123 Lookup lookup; 125 126 if (toolsAction instanceof Lookup.Provider) { 127 lookup = ((Lookup.Provider) toolsAction).getLookup(); 128 } else { 129 lookup = null; 130 } 131 132 for (int i = 0; i < actions.length; i++) { 133 Action a; 134 135 if ((lookup != null) && actions[i] instanceof ContextAwareAction) { 137 a = ((ContextAwareAction) actions[i]).createContextAwareInstance(lookup); 138 } else { 139 a = actions[i]; 140 } 141 142 if (a == null) { 143 if (firstItemAdded) { 144 separator = true; 145 } 146 } else { 147 boolean isPopup = (a instanceof Presenter.Popup); 148 boolean isMenu = (a instanceof Presenter.Menu); 149 150 if (!((forMenu && isMenu) || (!forMenu && isPopup)) && (isMenu || isPopup)) { 151 continue; } 153 154 if (a.isEnabled()) { 155 JMenuItem mi; 156 157 if (forMenu && isMenu) { 158 mi = ((Presenter.Menu) a).getMenuPresenter(); 159 } else if (!forMenu && isPopup) { 160 mi = ((Presenter.Popup) a).getPopupPresenter(); 161 } else if (!isMenu && !isPopup) { 162 mi = new JMenuItem(); 164 Actions.connect(mi, a, !forMenu); 165 } else { 166 continue; 168 } 169 170 if (separator) { 171 list.add(null); 172 separator = false; 173 } 174 175 list.add(mi); 176 firstItemAdded = true; 177 } 178 } 179 } 180 181 return list; 182 } 183 184 186 187 public static void setModel(Model m) { 188 throw new SecurityException (); 189 } 190 191 192 public static interface Model { 193 public SystemAction[] getActions(); 194 195 public void addChangeListener(javax.swing.event.ChangeListener l); 196 197 public void removeChangeListener(javax.swing.event.ChangeListener l); 198 } 199 200 202 private static final class Inline extends JMenuItem implements DynamicMenuContent { 203 static final long serialVersionUID = 2269006599727576059L; 204 205 206 private int timestamp = 0; 207 208 209 private Action toolsAction; 210 211 Inline(Action toolsAction) { 212 this.toolsAction = toolsAction; 213 } 214 215 216 217 public JComponent[] synchMenuPresenters(JComponent[] items) { 218 if (timestamp == gl().getTimestamp()) { 219 return items; 220 } 221 List l = generate(toolsAction, true); 223 timestamp = gl().getTimestamp(); 224 return (JMenuItem[]) l.toArray(new JMenuItem[l.size()]); 225 } 226 227 228 public JComponent[] getMenuPresenters() { 229 return synchMenuPresenters(new JComponent[0]); 230 } 231 } 232 233 235 236 private static final class Popup extends JMenuItem implements DynamicMenuContent { 237 static final long serialVersionUID = 2269006599727576059L; 238 239 240 private JMenu menu = new MyMenu(); 241 242 243 private Action toolsAction; 244 245 public Popup(Action toolsAction) { 246 super(); 247 this.toolsAction = toolsAction; 248 HelpCtx.setHelpIDString(menu, ToolsAction.class.getName()); 249 250 } 251 252 253 public JComponent[] synchMenuPresenters(JComponent[] items) { 254 return gl().isPopupEnabled(toolsAction) ? new JMenuItem[] { menu } : new JMenuItem[0]; 255 } 256 257 258 public JComponent[] getMenuPresenters() { 259 return synchMenuPresenters(new JComponent[0]); 260 } 261 262 263 264 private class MyMenu extends org.openide.awt.JMenuPlus implements PopupMenuListener { 265 267 private JPopupMenu lastPopup = null; 268 269 MyMenu() { 270 super(getActionName()); 271 } 272 273 public JPopupMenu getPopupMenu() { 274 JPopupMenu popup = super.getPopupMenu(); 275 fillSubmenu(popup); 276 277 return popup; 278 } 279 280 private void fillSubmenu(JPopupMenu pop) { 281 if (lastPopup == null) { 282 pop.addPopupMenuListener(this); 283 lastPopup = pop; 284 285 removeAll(); 286 287 Iterator it = generate(toolsAction, false).iterator(); 288 289 while (it.hasNext()) { 290 java.awt.Component item = (java.awt.Component ) it.next(); 291 292 if (item == null) { 293 addSeparator(); 294 } else { 295 add(item); 296 } 297 } 298 299 if (getMenuComponentCount() == 0) { 301 JMenuItem empty = new JMenuItem(NbBundle.getMessage(ToolsAction.class, "CTL_EmptySubMenu")); 302 empty.setEnabled(false); 303 add(empty); 304 } 305 } 306 } 307 308 public void popupMenuCanceled(PopupMenuEvent e) { 309 } 310 311 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 312 } 313 314 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 315 lastPopup.removePopupMenuListener(this); 316 lastPopup = null; } 318 } 319 } 320 321 private static class G implements PropertyChangeListener { 324 public static final String PROP_STATE = "actionsState"; private int timestamp = 1; 326 private SystemAction[] actions = null; 327 private PropertyChangeSupport supp = new PropertyChangeSupport(this); 328 329 public G() { 330 ActionManager am = ActionManager.getDefault(); 331 am.addPropertyChangeListener(this); 332 actionsListChanged(); 333 } 334 335 public final void addPropertyChangeListener(PropertyChangeListener listener) { 336 supp.addPropertyChangeListener(listener); 337 } 338 339 public final void removePropertyChangeListener(PropertyChangeListener listener) { 340 supp.removePropertyChangeListener(listener); 341 } 342 343 protected final void firePropertyChange(String name, Object o, Object n) { 344 supp.firePropertyChange(name, o, n); 345 } 346 347 private void actionsListChanged() { 348 timestamp++; 349 350 SystemAction[] copy = actions; 352 353 if (copy != null) { 354 for (int i = 0; i < copy.length; i++) { 355 SystemAction act = copy[i]; 356 357 if (act != null) { 358 act.removePropertyChangeListener(this); 359 } 360 } 361 } 362 363 ActionManager am = ActionManager.getDefault(); 364 copy = am.getContextActions(); 365 366 for (int i = 0; i < copy.length; i++) { 367 SystemAction act = copy[i]; 368 369 if (act != null) { 370 act.addPropertyChangeListener(this); 371 } 372 } 373 374 actions = copy; 375 376 firePropertyChange(PROP_STATE, null, null); } 378 379 private void actionStateChanged() { 380 timestamp++; 381 firePropertyChange(PROP_STATE, null, null); } 383 384 public void propertyChange(PropertyChangeEvent ev) { 385 String prop = ev.getPropertyName(); 386 387 if ((prop == null) || prop.equals(ActionManager.PROP_CONTEXT_ACTIONS)) { 388 actionsListChanged(); 389 } else if (prop.equals(SystemAction.PROP_ENABLED)) { 390 actionStateChanged(); 391 } 392 } 393 394 397 private boolean isPopupEnabled(Action toolsAction) { 398 boolean en = false; 399 SystemAction[] copy = actions; 400 401 Lookup lookup; 403 404 if (toolsAction instanceof Lookup.Provider) { 405 lookup = ((Lookup.Provider) toolsAction).getLookup(); 406 } else { 407 lookup = null; 408 } 409 410 for (int i = 0; i < copy.length; i++) { 411 Action act; 413 414 if ((lookup != null) && copy[i] instanceof ContextAwareAction) { 416 act = ((ContextAwareAction) copy[i]).createContextAwareInstance(lookup); 417 } else { 418 act = copy[i]; 419 } 420 421 if (act instanceof Presenter.Popup && act.isEnabled()) { 422 en = true; 423 424 break; 425 } 426 } 427 428 return en; 429 } 430 431 private int getTimestamp() { 432 return timestamp; 433 } 434 } 435 436 438 private static final class DelegateAction extends Object implements Action, Presenter.Menu, Presenter.Popup, 439 Lookup.Provider { 440 private ToolsAction delegate; 441 private Lookup lookup; 442 443 444 private PropertyChangeSupport support = new PropertyChangeSupport(this); 445 446 public DelegateAction(ToolsAction delegate, Lookup actionContext) { 447 this.delegate = delegate; 448 this.lookup = actionContext; 449 } 450 451 452 public String toString() { 453 return super.toString() + "[delegate=" + delegate + "]"; } 455 456 457 public Lookup getLookup() { 458 return lookup; 459 } 460 461 public void actionPerformed(java.awt.event.ActionEvent e) { 462 } 463 464 public void putValue(String key, Object o) { 465 } 466 467 public Object getValue(String key) { 468 return delegate.getValue(key); 469 } 470 471 public boolean isEnabled() { 472 return delegate.isEnabled(); 474 } 475 476 public void setEnabled(boolean b) { 477 } 479 480 public void addPropertyChangeListener(PropertyChangeListener listener) { 481 support.addPropertyChangeListener(listener); 482 } 483 484 public void removePropertyChangeListener(PropertyChangeListener listener) { 485 support.removePropertyChangeListener(listener); 486 } 487 488 489 public javax.swing.JMenuItem getMenuPresenter() { 490 return new Inline(this); 491 } 492 493 494 public javax.swing.JMenuItem getPopupPresenter() { 495 return new ToolsAction.Popup(this); 496 } 497 } 498 } 500 | Popular Tags |