用了一个TreeViewer,绑定了Ctrl+C,Ctrl+V等快捷键,有自己的Action进行复制、粘贴等处理。
发现,点击单元格,出现TextCellEditor时,无法在文本框内使用Ctrl+C,Ctrl+V等快捷键了,相应动作都被Treeviewer执行了。
试了一下,单独的一个Text框是支持剪切、复制、粘贴和Delete这些快捷键的。
说明,Treeviewer和列编辑器中的Text框的快捷键出现了冲突,前者占了上风~~~
困惑了很久,根本不知道搜啥,今天又搜索了一天,终于看到一个提到这个问题的文章。 http://eclipse.dzone.com/articles/key-bindings-eclipse-editors
抄过来,改改,如下:
import java.util.ArrayList; import java.util.List;
import org.eclipse.core.commands.IHandler; import org.eclipse.core.expressions.EvaluationResult; import org.eclipse.core.expressions.Expression; import org.eclipse.core.expressions.ExpressionInfo; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.Action; import org.eclipse.jface.commands.ActionHandler; import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.handlers.IHandlerActivation; import org.eclipse.ui.handlers.IHandlerService;
/** * 列编辑器中的Text框支持类. */ public class TextCellEditorSupport implements FocusListener, DisposeListener {
/** 列编辑器对象. */ private TextCellEditor textEditor = null;
/** 文本框对象. */ private Text text = null;
/** The handler service. */ private IHandlerService handlerService = null;
/** The handler activations. */ private List<IHandlerActivation> handlerActivations = new ArrayList<IHandlerActivation>();
/** * 构造方法. * * @param textEditor * 列编辑器对象 * @param handlerService * HandlerService对象 */ public TextCellEditorSupport(TextCellEditor textEditor, IHandlerService handlerService) { this.textEditor = textEditor; this.text = (Text) textEditor.getControl(); this.handlerService = handlerService; }
/** * 失去焦点时,删除快捷键定义. */ public void focusLost(FocusEvent e) { deactivateContext(); }
/** * 获得焦点时,追加快捷键定义. */ public void focusGained(FocusEvent e) {
// 初始光标位置定位到最后 Text text = (Text) e.widget; text.setSelection(text.getText().length());
// 追加快捷键定义 activateContext(); }
/** * 销毁时,删除快捷键定义. */ public void widgetDisposed(DisposeEvent e) { deactivateContext(); }
/** * 追加快捷键定义. */ protected void activateContext() { if (handlerActivations.isEmpty()) { activateHandler(ITextOperationTarget.CUT, IWorkbenchCommandConstants.EDIT_CUT); activateHandler(ITextOperationTarget.COPY, IWorkbenchCommandConstants.EDIT_COPY); activateHandler(ITextOperationTarget.PASTE, IWorkbenchCommandConstants.EDIT_PASTE); activateHandler(ITextOperationTarget.DELETE, IWorkbenchCommandConstants.EDIT_DELETE); activateHandler(ITextOperationTarget.UNDO, IWorkbenchCommandConstants.EDIT_UNDO); activateHandler(ITextOperationTarget.REDO, IWorkbenchCommandConstants.EDIT_REDO); activateHandler(ITextOperationTarget.SELECT_ALL, IWorkbenchCommandConstants.EDIT_SELECT_ALL); } }
/** * 追加快捷键定义. * * @param operation * 动作ID * @param actionDefinitionId * Action定义ID */ protected void activateHandler(int operation, String actionDefinitionId) {
IHandler actionHandler = createActionHandler(operation, actionDefinitionId); IHandlerActivation handlerActivation = handlerService.activateHandler( actionDefinitionId, actionHandler, new ActiveFocusControlExpression(text)); handlerActivations.add(handlerActivation); }
/** * 创建Handler对象. * * @param operation * 动作ID * @param actionDefinitionId * Action定义ID * @return Handler对象 */ private IHandler createActionHandler(final int operation, String actionDefinitionId) { Action action = new Action() { @Override public void run() { if (operation == ITextOperationTarget.CUT) { if (textEditor.isCutEnabled()) { textEditor.performCut(); } } else if (operation == ITextOperationTarget.COPY) { if (textEditor.isCopyEnabled()) { textEditor.performCopy(); } } else if (operation == ITextOperationTarget.PASTE) { if (textEditor.isPasteEnabled()) { textEditor.performPaste(); } } else if (operation == ITextOperationTarget.DELETE) { if (textEditor.isDeleteEnabled()) { textEditor.performDelete(); } } else if (operation == ITextOperationTarget.SELECT_ALL) { if (textEditor.isSelectAllEnabled()) { textEditor.performSelectAll(); } } else if (operation == ITextOperationTarget.UNDO) { if (textEditor.isUndoEnabled()) { textEditor.performUndo(); } } else if (operation == ITextOperationTarget.REDO) { if (textEditor.isRedoEnabled()) { textEditor.performRedo(); } } } }; action.setActionDefinitionId(actionDefinitionId); return new ActionHandler(action); }
/** * 删除快捷键定义. */ protected void deactivateContext() { if (!handlerActivations.isEmpty()) { for (IHandlerActivation activation : handlerActivations) { handlerService.deactivateHandler(activation); activation.getHandler().dispose(); } handlerActivations.clear(); } }
/** * 文本框的表达式类. * * 多个Action具有同一个快捷键时,平台核心会比较表达式,调用优先级高的Action。 */ protected class ActiveFocusControlExpression extends Expression {
private Control focusControl;
public ActiveFocusControlExpression(Control control) { focusControl = control; }
@Override public void collectExpressionInfo(ExpressionInfo info) { info.markDefaultVariableAccessed(); // 高优先级 info.addVariableNameAccess(ISources.ACTIVE_SHELL_NAME); info.addVariableNameAccess(ISources.ACTIVE_WORKBENCH_WINDOW_NAME); }
@Override public EvaluationResult evaluate(IEvaluationContext context) throws CoreException { if (Display.getCurrent() != null && focusControl.isFocusControl()) { return EvaluationResult.TRUE; } return EvaluationResult.FALSE; } } }
用法举例如下:
// 文本框追加Focus事件支持 TextCellEditor textEditor = (TextCellEditor) cellEditor[0]; Text text = (Text) textEditor.getControl(); IHandlerService handlerService = (IHandlerService) editor.getSite() .getService(IHandlerService.class); //editor变量是编辑器对象,你可以通过你的相应方法得到Site对象就行了。 TextCellEditorSupport support = new TextCellEditorSupport(textEditor, handlerService); text.addFocusListener(support); text.addDisposeListener(support);
RCP开发感觉好繁杂,各种小窍门太多了~~~~
|