自己扩展CNF之后,导航栏的删除、复制、黏贴等快捷键失效了,在网上搜索了半天,结果最终不如自己看源码。
本篇文章的主要目的不止于解决快捷键失效,更在于如何处理类似的问题,如何利用debug快速定位。这种解决问题的思路能帮助我们更加理解他人的代码,快速熟悉一套陌生的框架。
1、理解问题的本质,为什么按键不生效?
在解决快捷键失效问题之前,我们需要理解快捷键是如何生效的。
为了更直观的理解,请使用debug模式打开一个新的Eclipse IDE,然后,对org.eclipse.jdt.internal.ui.refactoring.reorg.CopyToClipboardAction这个类的run方法加上断点。在新的EclipseIDE的Package Explorer上选中一个节点,按CTRL+C
在DEBUG视图中显示如下图所示:
我们过一眼这些类名和方法名,如果你是个有经验的程序员,那么,你应当能敏感的发现WorkbenchKeyboard就是是你需要的那个类。
我们看看executeCommand方法,关键代码标记上了红色。
final boolean executeCommand(final Binding binding, final Event trigger) throws CommandException { final ParameterizedCommand parameterizedCommand = binding .getParameterizedCommand(); if (DEBUG) { Tracing.printTrace("KEYS", //$NON-NLS-1$ "WorkbenchKeyboard.executeCommand(commandId = '" //$NON-NLS-1$ + parameterizedCommand.getId() + "', parameters = " //$NON-NLS-1$ + parameterizedCommand.getParameterMap() + ')'); } // Reset the key binding state (close window, clear status line, etc.) resetState(false); // Dispatch to the handler. final IHandlerService handlerService = (IHandlerService) workbench .getService(IHandlerService.class); final Command command = parameterizedCommand.getCommand(); final boolean commandDefined = command.isDefined(); final boolean commandHandled = command.isHandled(); command.setEnabled(handlerService.getCurrentState()); final boolean commandEnabled = command.isEnabled(); if (DEBUG && DEBUG_VERBOSE) { if (!commandDefined) { Tracing.printTrace("KEYS", " not defined"); //$NON-NLS-1$ //$NON-NLS-2$ } else if (!commandHandled) { Tracing.printTrace("KEYS", " not handled"); //$NON-NLS-1$ //$NON-NLS-2$ } else if (!commandEnabled) { Tracing.printTrace("KEYS", " not enabled"); //$NON-NLS-1$ //$NON-NLS-2$ } } try { handlerService.executeCommand(parameterizedCommand, trigger); } catch (final NotDefinedException e) { // The command is not defined. Forwarded to the IExecutionListener. } catch (final NotEnabledException e) { // The command is not enabled. Forwarded to the IExecutionListener. } catch (final NotHandledException e) { // There is no handler. Forwarded to the IExecutionListener. } /* * Now that the command has executed (and had the opportunity to use the * remembered state of the dialog), it is safe to delete that * information. */ if (keyAssistDialog != null) { keyAssistDialog.clearRememberedState(); } return (commandDefined && commandHandled); }
我们发现了binding这个对象。binding的注释如下:
org.eclipse.jface.bindings.Binding
A binding is a link between user input and the triggering of a particular command. The most common example of a binding is a keyboard shortcut, but there are also mouse and gesture bindings.