001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.debugger.ui.actions;
043:
044: import java.awt.event.ActionEvent;
045: import java.beans.PropertyChangeEvent;
046: import java.lang.ref.WeakReference;
047: import javax.swing.AbstractAction;
048: import javax.swing.Action;
049: import javax.swing.ImageIcon;
050: import javax.swing.SwingUtilities;
051:
052: import org.netbeans.api.debugger.ActionsManager;
053: import org.netbeans.api.debugger.ActionsManagerListener;
054: import org.netbeans.api.debugger.DebuggerEngine;
055: import org.netbeans.api.debugger.DebuggerManager;
056: import org.netbeans.api.debugger.DebuggerManagerAdapter;
057:
058: import org.netbeans.modules.debugger.ui.Utils;
059:
060: import org.netbeans.spi.project.ui.support.FileSensitiveActions;
061:
062: import org.openide.util.NbBundle;
063: import org.openide.util.Utilities;
064:
065: /**
066: *
067: * @author Jan Jancura
068: */
069: public class DebuggerAction extends AbstractAction {
070:
071: private Object action;
072:
073: private DebuggerAction(Object action) {
074: this .action = action;
075: new Listener(this );
076: setEnabled(isEnabled(getAction()));
077: }
078:
079: public Object getAction() {
080: return action;
081: }
082:
083: public Object getValue(String key) {
084: if (key == Action.NAME) {
085: return NbBundle.getMessage(DebuggerAction.class,
086: (String) super .getValue(key));
087: }
088: Object value = super .getValue(key);
089: if (key == Action.SMALL_ICON) {
090: if (value instanceof String) {
091: value = Utils.getIcon((String) value);
092: }
093: }
094: return value;
095: }
096:
097: public void actionPerformed(ActionEvent evt) {
098: // Post the action asynchronously, since we're on AWT
099: getActionsManager(action).postAction(action);
100: }
101:
102: /**
103: * Get the actions manager of the current engine (if any).
104: * @return The actions manager or <code>null</code>.
105: */
106: private static ActionsManager getCurrentEngineActionsManager() {
107: DebuggerEngine engine = DebuggerManager.getDebuggerManager()
108: .getCurrentEngine();
109: if (engine != null) {
110: return engine.getActionsManager();
111: } else {
112: return null;
113: }
114: }
115:
116: /**
117: * Test whether the given action is enabled in either the current engine's
118: * action manager, or the default action manager.
119: * We need to take the default actions into account so that actions provided
120: * by other debuggers are not ignored.
121: */
122: private static boolean isEnabled(Object action) {
123: ActionsManager manager = getCurrentEngineActionsManager();
124: if (manager != null) {
125: if (manager.isEnabled(action)) {
126: return true;
127: }
128: }
129: return DebuggerManager.getDebuggerManager().getActionsManager()
130: .isEnabled(action);
131: }
132:
133: /**
134: * Get the actions manager for which the action is enabled.
135: * It returns either the current engine's manager, or the default one.
136: * @param the action
137: * @return the actions manager
138: */
139: private static ActionsManager getActionsManager(Object action) {
140: ActionsManager manager = getCurrentEngineActionsManager();
141: if (manager != null) {
142: if (manager.isEnabled(action)) {
143: return manager;
144: }
145: }
146: return DebuggerManager.getDebuggerManager().getActionsManager();
147: }
148:
149: public static DebuggerAction createContinueAction() {
150: DebuggerAction action = new DebuggerAction(
151: ActionsManager.ACTION_CONTINUE);
152: action.putValue(Action.NAME, "CTL_Continue_action_name");
153: action.putValue(Action.SMALL_ICON,
154: "org/netbeans/modules/debugger/resources/actions/Continue" // NOI18N
155: );
156: action.putValue("iconBase", // NOI18N
157: "org/netbeans/modules/debugger/resources/actions/Continue.gif" // NOI18N
158: );
159: return action;
160: }
161:
162: public static DebuggerAction createFixAction() {
163: DebuggerAction action = new DebuggerAction(
164: ActionsManager.ACTION_FIX);
165: action.putValue(Action.NAME, "CTL_Fix_action_name");
166: action.putValue(Action.SMALL_ICON,
167: "org/netbeans/modules/debugger/resources/actions/Fix" // NOI18N
168: );
169: action.putValue("iconBase",
170: "org/netbeans/modules/debugger/resources/actions/Fix.gif" // NOI18N
171: );
172: return action;
173: }
174:
175: public static DebuggerAction createKillAction() {
176: DebuggerAction action = new DebuggerAction(
177: ActionsManager.ACTION_KILL);
178: action.putValue(Action.NAME, "CTL_KillAction_name");
179: action.putValue(Action.SMALL_ICON,
180: "org/netbeans/modules/debugger/resources/actions/Kill" // NOI18N
181: );
182: action.putValue("iconBase", // NOI18N
183: "org/netbeans/modules/debugger/resources/actions/Kill.gif" // NOI18N
184: );
185: action.setEnabled(false);
186: return action;
187: }
188:
189: public static DebuggerAction createMakeCalleeCurrentAction() {
190: DebuggerAction action = new DebuggerAction(
191: ActionsManager.ACTION_MAKE_CALLEE_CURRENT);
192: action
193: .putValue(Action.NAME,
194: "CTL_MakeCalleeCurrentAction_name");
195: action.putValue(Action.SMALL_ICON,
196: "org/netbeans/modules/debugger/resources/actions/GoToCalledMethod" // NOI18N
197: );
198: action.putValue("iconBase", // NOI18N
199: "org/netbeans/modules/debugger/resources/actions/GoToCalledMethod.gif" // NOI18N
200: );
201: return action;
202: }
203:
204: public static DebuggerAction createMakeCallerCurrentAction() {
205: DebuggerAction action = new DebuggerAction(
206: ActionsManager.ACTION_MAKE_CALLER_CURRENT);
207: action
208: .putValue(Action.NAME,
209: "CTL_MakeCallerCurrentAction_name");
210: action.putValue(Action.SMALL_ICON,
211: "org/netbeans/modules/debugger/resources/actions/GoToCallingMethod" // NOI18N
212: );
213: action.putValue("iconBase", // NOI18N
214: "org/netbeans/modules/debugger/resources/actions/GoToCallingMethod.gif" // NOI18N
215: );
216: return action;
217: }
218:
219: public static DebuggerAction createPauseAction() {
220: DebuggerAction action = new DebuggerAction(
221: ActionsManager.ACTION_PAUSE);
222: action.putValue(Action.NAME, "CTL_Pause_action_name");
223: action.putValue(Action.SMALL_ICON,
224: "org/netbeans/modules/debugger/resources/actions/Pause" // NOI18N
225: );
226: action.putValue("iconBase", // NOI18N
227: "org/netbeans/modules/debugger/resources/actions/Pause.gif" // NOI18N
228: );
229: return action;
230: }
231:
232: public static DebuggerAction createPopTopmostCallAction() {
233: DebuggerAction action = new DebuggerAction(
234: ActionsManager.ACTION_POP_TOPMOST_CALL);
235: action.putValue(Action.NAME, "CTL_PopTopmostCallAction_name");
236: return action;
237: }
238:
239: public static DebuggerAction createRunIntoMethodAction() {
240: DebuggerAction action = new DebuggerAction(
241: ActionsManager.ACTION_RUN_INTO_METHOD);
242: action.putValue(Action.NAME, "CTL_Run_into_method_action_name");
243: return action;
244: }
245:
246: public static DebuggerAction createRunToCursorAction() {
247: DebuggerAction action = new DebuggerAction(
248: ActionsManager.ACTION_RUN_TO_CURSOR);
249: action.putValue(Action.NAME, "CTL_Run_to_cursor_action_name");
250: action.putValue(Action.SMALL_ICON,
251: "org/netbeans/modules/debugger/resources/actions/RunToCursor" // NOI18N
252: );
253: action.putValue("iconBase", // NOI18N
254: "org/netbeans/modules/debugger/resources/actions/RunToCursor.gif" // NOI18N
255: );
256: return action;
257: }
258:
259: public static DebuggerAction createStepIntoAction() {
260: DebuggerAction action = new DebuggerAction(
261: ActionsManager.ACTION_STEP_INTO);
262: action.putValue(Action.NAME, "CTL_Step_into_action_name");
263: action.putValue(Action.SMALL_ICON,
264: "org/netbeans/modules/debugger/resources/actions/StepInto" // NOI18N
265: );
266: action.putValue("iconBase", // NOI18N
267: "org/netbeans/modules/debugger/resources/actions/StepInto.gif" // NOI18N
268: );
269: return action;
270: }
271:
272: public static DebuggerAction createStepOutAction() {
273: DebuggerAction action = new DebuggerAction(
274: ActionsManager.ACTION_STEP_OUT);
275: action.putValue(Action.NAME, "CTL_Step_out_action_name");
276: action.putValue(Action.SMALL_ICON,
277: "org/netbeans/modules/debugger/resources/actions/StepOut" // NOI18N
278: );
279: action.putValue("iconBase", // NOI18N
280: "org/netbeans/modules/debugger/resources/actions/StepOut.gif" // NOI18N
281: );
282: return action;
283: }
284:
285: public static DebuggerAction createStepOverAction() {
286: DebuggerAction action = new DebuggerAction(
287: ActionsManager.ACTION_STEP_OVER);
288: action.putValue(Action.NAME, "CTL_Step_over_action_name");
289: action.putValue(Action.SMALL_ICON,
290: "org/netbeans/modules/debugger/resources/actions/StepOver" // NOI18N
291: );
292: action.putValue("iconBase", // NOI18N
293: "org/netbeans/modules/debugger/resources/actions/StepOver.gif" // NOI18N
294: );
295: return action;
296: }
297:
298: public static DebuggerAction createStepOperationAction() {
299: DebuggerAction action = new DebuggerAction(
300: ActionsManager.ACTION_STEP_OPERATION);
301: action.putValue(Action.NAME, "CTL_Step_operation_action_name");
302: action.putValue(Action.SMALL_ICON,
303: "org/netbeans/modules/debugger/resources/actions/StepOverOperation" // NOI18N
304: );
305: action.putValue("iconBase", // NOI18N
306: "org/netbeans/modules/debugger/resources/actions/StepOverOperation.gif" // NOI18N
307: );
308: return action;
309: }
310:
311: public static DebuggerAction createToggleBreakpointAction() {
312: DebuggerAction action = new DebuggerAction(
313: ActionsManager.ACTION_TOGGLE_BREAKPOINT);
314: action.putValue(Action.NAME, "CTL_Toggle_breakpoint");
315: return action;
316: }
317:
318: // Debug File Actions:
319:
320: public static Action createDebugFileAction() {
321: Action a = FileSensitiveActions
322: .fileCommandAction(
323: "debug.single", // XXX Define standard
324: NbBundle.getMessage(DebuggerAction.class,
325: "LBL_DebugSingleAction_Name"), // NOI18N
326: new ImageIcon(
327: Utilities
328: .loadImage("org/netbeans/modules/debugger/resources/debugSingle.png"))); //NOI18N
329: a
330: .putValue("iconBase",
331: "org/netbeans/modules/debugger/resources/debugSingle.png"); //NOI18N
332: a.putValue("noIconInMenu", Boolean.TRUE); //NOI18N
333: return a;
334: }
335:
336: public static Action createDebugTestFileAction() {
337: Action a = FileSensitiveActions
338: .fileCommandAction(
339: "debug.test.single", // XXX Define standard
340: NbBundle.getMessage(DebuggerAction.class,
341: "LBL_DebugTestSingleAction_Name"),// NOI18N
342: new ImageIcon(
343: Utilities
344: .loadImage("org/netbeans/modules/debugger/resources/debugTestSingle.png"))); //NOI18N
345: a
346: .putValue("iconBase",
347: "org/netbeans/modules/debugger/resources/debugTestSingle.png"); //NOI18N
348: a.putValue("noIconInMenu", Boolean.TRUE); //NOI18N
349: return a;
350: }
351:
352: // innerclasses ............................................................
353:
354: /**
355: * Listens on DebuggerManager on PROP_CURRENT_ENGINE and on current engine
356: * on PROP_ACTION_STATE and updates state of this action instance.
357: */
358: static class Listener extends DebuggerManagerAdapter implements
359: ActionsManagerListener {
360:
361: private ActionsManager currentActionsManager;
362: private WeakReference ref;
363:
364: Listener(DebuggerAction da) {
365: ref = new WeakReference(da);
366: DebuggerManager.getDebuggerManager().addDebuggerListener(
367: DebuggerManager.PROP_CURRENT_ENGINE, this );
368: DebuggerManager
369: .getDebuggerManager()
370: .getActionsManager()
371: .addActionsManagerListener(
372: ActionsManagerListener.PROP_ACTION_STATE_CHANGED,
373: this );
374: updateCurrentActionsManager();
375: }
376:
377: public void propertyChange(PropertyChangeEvent evt) {
378: final DebuggerAction da = getDebuggerAction();
379: if (da == null)
380: return;
381: updateCurrentActionsManager();
382: final boolean en = DebuggerAction.isEnabled(da.getAction());
383: SwingUtilities.invokeLater(new Runnable() {
384: public void run() {
385: da.setEnabled(en);
386: }
387: });
388: }
389:
390: public void actionPerformed(Object action) {
391: }
392:
393: public void actionStateChanged(final Object action,
394: final boolean enabled) {
395: final DebuggerAction da = getDebuggerAction();
396: if (da == null)
397: return;
398: if (action != da.getAction())
399: return;
400: // ignore the enabled argument, check it with respect to the proper
401: // actions manager.
402: final boolean en = DebuggerAction.isEnabled(da.getAction());
403: SwingUtilities.invokeLater(new Runnable() {
404: public void run() {
405: da.setEnabled(en);
406: }
407: });
408: }
409:
410: private void updateCurrentActionsManager() {
411: ActionsManager newActionsManager = getCurrentEngineActionsManager();
412: if (currentActionsManager == newActionsManager)
413: return;
414:
415: if (currentActionsManager != null)
416: currentActionsManager
417: .removeActionsManagerListener(
418: ActionsManagerListener.PROP_ACTION_STATE_CHANGED,
419: this );
420: if (newActionsManager != null)
421: newActionsManager
422: .addActionsManagerListener(
423: ActionsManagerListener.PROP_ACTION_STATE_CHANGED,
424: this );
425: currentActionsManager = newActionsManager;
426: }
427:
428: private DebuggerAction getDebuggerAction() {
429: DebuggerAction da = (DebuggerAction) ref.get();
430: if (da == null) {
431: DebuggerManager.getDebuggerManager()
432: .removeDebuggerListener(
433: DebuggerManager.PROP_CURRENT_ENGINE,
434: this);
435: DebuggerManager
436: .getDebuggerManager()
437: .getActionsManager()
438: .removeActionsManagerListener(
439: ActionsManagerListener.PROP_ACTION_STATE_CHANGED,
440: this);
441: if (currentActionsManager != null)
442: currentActionsManager
443: .removeActionsManagerListener(
444: ActionsManagerListener.PROP_ACTION_STATE_CHANGED,
445: this);
446: currentActionsManager = null;
447: return null;
448: }
449: return da;
450: }
451: }
452: }
|