Lines 13-18
Link Here
|
13 |
|
13 |
|
14 |
package org.openide.util.actions; |
14 |
package org.openide.util.actions; |
15 |
|
15 |
|
|
|
16 |
import org.openide.ErrorManager; |
16 |
import org.openide.util.WeakListeners; |
17 |
import org.openide.util.WeakListeners; |
17 |
import java.beans.*; |
18 |
import java.beans.*; |
18 |
import java.awt.Component; |
19 |
import java.awt.Component; |
Lines 73-79
Link Here
|
73 |
setSurviveFocusChange(false); |
74 |
setSurviveFocusChange(false); |
74 |
} |
75 |
} |
75 |
|
76 |
|
76 |
|
|
|
77 |
/** Get the current action performer. |
77 |
/** Get the current action performer. |
78 |
* @return the current action performer, or <code>null</code> if there is currently no performer |
78 |
* @return the current action performer, or <code>null</code> if there is currently no performer |
79 |
*/ |
79 |
*/ |
Lines 121-133
Link Here
|
121 |
/** Updates the enabled state by checking performer and ActionMap |
121 |
/** Updates the enabled state by checking performer and ActionMap |
122 |
*/ |
122 |
*/ |
123 |
private void updateEnabled () { |
123 |
private void updateEnabled () { |
124 |
javax.swing.Action action = findGlobalContextAction (); |
124 |
javax.swing.Action action = GlobalManager.getDefault ().findGlobalAction (getActionMapKey (), getSurviveFocusChange ()); |
125 |
if(action != null) { |
125 |
if(action != null) { |
126 |
setEnabled (action.isEnabled()); |
126 |
setEnabled (action.isEnabled()); |
127 |
|
127 |
|
128 |
synchronized (LISTENER) { |
128 |
synchronized (LISTENER) { |
129 |
ActionDelegateListener l = (ActionDelegateListener)getProperty(LISTENER); |
129 |
ActionDelegateListener l = (ActionDelegateListener)getProperty(LISTENER); |
130 |
if (l == null) { |
130 |
if (l == null || l.get () != this) { |
131 |
l = new ActionDelegateListener (this, action); |
131 |
l = new ActionDelegateListener (this, action); |
132 |
putProperty (LISTENER, l); |
132 |
putProperty (LISTENER, l); |
133 |
} else { |
133 |
} else { |
Lines 163-169
Link Here
|
163 |
*/ |
163 |
*/ |
164 |
public void actionPerformed(final ActionEvent ev) { |
164 |
public void actionPerformed(final ActionEvent ev) { |
165 |
// First try global context action. |
165 |
// First try global context action. |
166 |
final Action action = findGlobalContextAction (); |
166 |
final Action action = GlobalManager.getDefault ().findGlobalAction (getActionMapKey (), getSurviveFocusChange ()); |
167 |
if (action != null) { |
167 |
if (action != null) { |
168 |
if (action.isEnabled()) { |
168 |
if (action.isEnabled()) { |
169 |
action.actionPerformed(ev); |
169 |
action.actionPerformed(ev); |
Lines 186-204
Link Here
|
186 |
Toolkit.getDefaultToolkit().beep(); |
186 |
Toolkit.getDefaultToolkit().beep(); |
187 |
} |
187 |
} |
188 |
|
188 |
|
189 |
/** Finds global context action (the one from activated component). |
|
|
190 |
* @return action for key of activated component or null |
191 |
*/ |
192 |
private javax.swing.Action findGlobalContextAction () { |
193 |
ActionMap map = GlobalManager.getDefault ().getActionMap (); |
194 |
if (map != null) { |
195 |
Object key = getActionMapKey(); |
196 |
return map.get (key); |
197 |
} |
198 |
|
199 |
return null; |
200 |
} |
201 |
|
202 |
/** Perform the action. |
189 |
/** Perform the action. |
203 |
* This default implementation calls the assigned action performer if it |
190 |
* This default implementation calls the assigned action performer if it |
204 |
* exists, otherwise does nothing. |
191 |
* exists, otherwise does nothing. |
Lines 295-310
Link Here
|
295 |
it = actions.iterator (); |
282 |
it = actions.iterator (); |
296 |
while (it.hasNext ()) { |
283 |
while (it.hasNext ()) { |
297 |
CallbackSystemAction a = (CallbackSystemAction)it.next (); |
284 |
CallbackSystemAction a = (CallbackSystemAction)it.next (); |
|
|
285 |
if (errLog) { |
286 |
err.log ("updateEnabled: " + a); // NOI18N |
287 |
} |
298 |
a.updateEnabled (); |
288 |
a.updateEnabled (); |
299 |
} |
289 |
} |
300 |
} |
290 |
} |
|
|
291 |
|
292 |
/** logging */ |
293 |
private static final ErrorManager err = ErrorManager.getDefault ().getInstance ("org.openide.util.actions.CallbackSystemAction"); // NOI18N |
294 |
private static final boolean errLog = err.isLoggable (err.INFORMATIONAL); |
301 |
|
295 |
|
302 |
/** Listener on a global context. |
296 |
/** Listener on a global context. |
303 |
*/ |
297 |
*/ |
304 |
private static final class GlobalManager implements LookupListener { |
298 |
private static final class GlobalManager implements LookupListener { |
305 |
private static GlobalManager instance; |
299 |
private static GlobalManager instance; |
306 |
private Lookup.Result result; |
300 |
private Lookup.Result result; |
307 |
private Reference actionMap; |
301 |
private Reference actionMap = new WeakReference (null); |
|
|
302 |
private final ActionMap survive = new ActionMap (); |
308 |
|
303 |
|
309 |
public synchronized static GlobalManager getDefault () { |
304 |
public synchronized static GlobalManager getDefault () { |
310 |
if (instance != null) return instance; |
305 |
if (instance != null) return instance; |
Lines 317-362
Link Here
|
317 |
new Lookup.Template (ActionMap.class) |
312 |
new Lookup.Template (ActionMap.class) |
318 |
); |
313 |
); |
319 |
result.addLookupListener(this); |
314 |
result.addLookupListener(this); |
|
|
315 |
resultChanged (null); |
320 |
} |
316 |
} |
321 |
|
317 |
|
322 |
public ActionMap getActionMap () { |
318 |
public Action findGlobalAction (Object key, boolean surviveFocusChange) { |
323 |
ActionMap a = (ActionMap)Utilities.actionsGlobalContext ().lookup (ActionMap.class); |
319 |
ActionMap map = (ActionMap)actionMap.get (); |
324 |
if (actionMap == null) { |
320 |
Action a = map == null ? null : map.get (key); |
325 |
actionMap = new WeakReference (a); |
321 |
|
|
|
322 |
if (surviveFocusChange) { |
323 |
if (a == null) { |
324 |
a = survive.get (key); |
325 |
if (a != null) { |
326 |
a = ((WeakAction)a).getDelegate (); |
327 |
} |
328 |
if (errLog) { |
329 |
err.log ("No action for key: " + key + " using delegate: " + a); // NOI18N |
330 |
} |
331 |
} else { |
332 |
if (errLog) { |
333 |
err.log ("New action for key: " + key + " put: " + a); |
334 |
} |
335 |
|
336 |
survive.put (key, new WeakAction (a)); |
337 |
} |
338 |
} |
339 |
if (errLog) { |
340 |
err.log ("Action for key: " + key + " is: " + a); // NOI18N |
326 |
} |
341 |
} |
327 |
return a; |
342 |
return a; |
328 |
} |
343 |
} |
329 |
|
344 |
|
330 |
/** Change all that do not survive ActionMap change */ |
345 |
/** Change all that do not survive ActionMap change */ |
331 |
public void resultChanged(org.openide.util.LookupEvent ev) { |
346 |
public void resultChanged(org.openide.util.LookupEvent ev) { |
332 |
if (actionMap == null || actionMap.get () != getActionMap ()) { |
347 |
ActionMap a = (ActionMap)Utilities.actionsGlobalContext ().lookup (ActionMap.class); |
333 |
actionMap = null; |
348 |
if (errLog) { |
334 |
clearActionPerformers (); |
349 |
err.log ("changed map : " + a); // NOI18N |
|
|
350 |
err.log ("previous map: " + actionMap.get ()); // NOI18N |
351 |
} |
352 |
if (a == actionMap.get ()) { |
353 |
return; |
354 |
} |
355 |
actionMap = new WeakReference (a); |
356 |
if (errLog) { |
357 |
err.log ("clearActionPerformers"); // NOI18N |
335 |
} |
358 |
} |
|
|
359 |
clearActionPerformers (); |
336 |
} |
360 |
} |
337 |
|
361 |
|
338 |
} // end of LookupListener |
362 |
} // end of LookupListener |
339 |
|
363 |
|
|
|
364 |
/** An action that holds a weak reference to other action. |
365 |
*/ |
366 |
private static final class WeakAction extends WeakReference implements Action { |
367 |
public WeakAction (Action delegate) { |
368 |
super (delegate); |
369 |
} |
370 |
|
371 |
public Action getDelegate () { |
372 |
return (Action)super.get (); |
373 |
} |
374 |
|
375 |
public Object getValue (String key) { |
376 |
throw new UnsupportedOperationException (); |
377 |
} |
378 |
|
379 |
public void putValue (String key, Object value) { |
380 |
throw new UnsupportedOperationException (); |
381 |
} |
382 |
|
383 |
public void actionPerformed (ActionEvent e) { |
384 |
throw new UnsupportedOperationException (); |
385 |
} |
386 |
|
387 |
public void removePropertyChangeListener (PropertyChangeListener listener) { |
388 |
throw new UnsupportedOperationException (); |
389 |
} |
390 |
|
391 |
public void addPropertyChangeListener (PropertyChangeListener listener) { |
392 |
throw new UnsupportedOperationException (); |
393 |
} |
394 |
|
395 |
public void setEnabled (boolean b) { |
396 |
throw new UnsupportedOperationException (); |
397 |
} |
398 |
|
399 |
public boolean isEnabled () { |
400 |
throw new UnsupportedOperationException (); |
401 |
} |
402 |
} |
403 |
|
340 |
/** A class that listens on changes in enabled state of an action |
404 |
/** A class that listens on changes in enabled state of an action |
341 |
* and updates the state of the action according to it. |
405 |
* and updates the state of the action according to it. |
342 |
*/ |
406 |
*/ |
343 |
private static final class ActionDelegateListener extends Object |
407 |
private static final class ActionDelegateListener extends WeakReference |
344 |
implements PropertyChangeListener { |
408 |
implements PropertyChangeListener { |
345 |
private CallbackSystemAction action; |
409 |
private WeakReference delegate; |
346 |
private javax.swing.Action delegate; |
|
|
347 |
|
348 |
public ActionDelegateListener (CallbackSystemAction c, javax.swing.Action delegate) { |
410 |
public ActionDelegateListener (CallbackSystemAction c, javax.swing.Action delegate) { |
349 |
this.action = c; |
411 |
super (c); |
350 |
this.delegate = delegate; |
412 |
this.delegate = new WeakReference (delegate); |
351 |
|
|
|
352 |
|
353 |
delegate.addPropertyChangeListener(this); |
413 |
delegate.addPropertyChangeListener(this); |
354 |
} |
414 |
} |
355 |
|
415 |
|
356 |
public void clear () { |
416 |
public void clear () { |
357 |
javax.swing.Action a; |
417 |
javax.swing.Action a; |
358 |
|
418 |
|
359 |
a = delegate; |
419 |
WeakReference d = delegate; |
|
|
420 |
a = d == null ? null : (javax.swing.Action)d.get (); |
360 |
if (a == null) return; |
421 |
if (a == null) return; |
361 |
delegate = null; |
422 |
delegate = null; |
362 |
|
423 |
|
Lines 364-389
Link Here
|
364 |
} |
425 |
} |
365 |
|
426 |
|
366 |
public void attach (javax.swing.Action action) { |
427 |
public void attach (javax.swing.Action action) { |
367 |
if (delegate == action) { |
428 |
WeakReference d = delegate; |
|
|
429 |
if (d != null && d.get () == action) { |
368 |
return; |
430 |
return; |
369 |
} |
431 |
} |
370 |
|
432 |
Action prev = (Action)d.get (); |
371 |
// reattaches to different action |
433 |
// reattaches to different action |
372 |
if (this.delegate != null) { |
434 |
if (prev != null) { |
373 |
this.delegate.removePropertyChangeListener(this); |
435 |
prev.removePropertyChangeListener(this); |
374 |
} |
436 |
} |
375 |
|
437 |
|
376 |
this.delegate = action; |
438 |
this.delegate = new WeakReference (action); |
377 |
action.addPropertyChangeListener(this); |
439 |
action.addPropertyChangeListener(this); |
378 |
} |
440 |
} |
379 |
|
441 |
|
380 |
|
442 |
|
381 |
public void propertyChange(java.beans.PropertyChangeEvent evt) { |
443 |
public void propertyChange(java.beans.PropertyChangeEvent evt) { |
382 |
synchronized (LISTENER) { |
444 |
synchronized (LISTENER) { |
383 |
if (delegate == null) return; |
445 |
WeakReference d = delegate; |
|
|
446 |
if (d == null || d.get () == null) return; |
447 |
} |
448 |
|
449 |
CallbackSystemAction c = (CallbackSystemAction)get (); |
450 |
if (c != null) { |
451 |
c.updateEnabled(); |
384 |
} |
452 |
} |
385 |
|
|
|
386 |
action.updateEnabled(); |
387 |
} |
453 |
} |
388 |
} |
454 |
} |
389 |
|
455 |
|