Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
回复
 
主题工具 显示模式
旧 2019-12-14, 20:13   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 在Mac版MATLAB中启用选项键快捷方式

从R2009b开始,MATLAB通过其Keyboard Shortcuts Preferences拥有了可定制的键盘快捷 。这对于在Mac上使用命令和控制来自定义快捷方式非常有效。

不幸的是,这些键绑定似乎无法覆盖MATLAB的内置字符映射。例如,如果我将option-f定义为cursor-next-word (la emacs),则它接受绑定。击中组合键,光标不会正确地移动到下一个词,但它另外打印茠字符!我相信这是从字符映射表(也许与输入映射表相反?)中获得的。 EditorMacroKeyBindings均不能覆盖此行为。

从一个与切向相关的问题中偶然发现了这个答案,这给了我希望。简而言之,他定义了一个Java类,该类可以处理键盘事件并将其替换为其他按键输入。但是,该解决方案只能在Windows上按规定使用。在Mac上运行需要进行以下修改:

我需要更改键码以重新映射字符串中的“按下”键,如下所示:

map = { '$' '^' '#' char(181) % might be useful for text formatting }; 至:

map = { 'alt pressed F' '^' 'alt pressed B' char(181) % might be useful for text formatting }; 不幸的是,在运行代码,按下Option-F键的产量后cursor-next-word和茠性格,就像以前一样。但是,如果我从首选项中禁用了cursor-next-word绑定,那么我会同时获得茠和^ !确实,即使我使用了一个简单的动作(例如pressed F ,KeyReplacementAction也不代替该动作,而是对其进行了增强 。似乎此行为是OS X上的MATLAB特有的。

似乎我只是没有覆盖正确的键盘映射。我已经尝试了Java运行时的挖掘,但是我对事件分发模型并不足够了解,因此不知道下一步该怎么看。也许在Java的操作系统级键盘映射中?

编辑 :从那以后我做了更多的挖掘。似乎Mac版本的MATLAB并未正确遵守keyEvent的'consumed'属性。我可以将KeyReplacementAction附加到inputMap或keymap ,在两种情况下,我都增加了键绑定而不是替换键绑定。我使用反射来“取消保护” AWTEvents的consume()方法,但效果与以前相同。

在堆栈跟踪之后,似乎keyEvent陷入了javax.swing.KeyboardManager的实例。看起来我应该能够在KeyboardManager中解除键击的绑定,但是我无法弄清楚如何从已有的MATLAB句柄访问实例。也许更熟悉Swing的事件模型和Java调试器的人可能会走得更远。

编辑2flolo的答案促使我研究X11的键盘映射。几点注意事项:
  • Matlab似乎不尊重~/.Xmodmap或任何当前加载的modmap。
  • 如果启动时存在,则Matlab将使用$XKEYSYMDB环境变量。否则,它将从$MATLAB/X11/app-defaults/XKeysymDB加载它。
  • 整个$MATLAB/X11/app-defaults/目录看起来非常有趣。也许那里的一些黑客可以使这项工作奏效?
  • Mac上的X11的键盘布局? MATLAB如何切换到国际键盘布局?
编辑3 :嗯,我认为X11是红色鲱鱼。 lsof -c MATLAB表明它正在访问/System/Library/Keyboard Layouts/AppleKeyboardLayouts.bundle 。现在就解决这个问题?? / p> 编辑4 :MATLAB确实确实使用了系统键盘布局。我创建了一个没有任何绑定的RM建议。这似乎起作用了?MATLAB的行为正常。不幸的是,它也破坏了我在所有其他程序中的自定义可可键绑定。关闭,但没有雪茄。 (实际上,由于简短地认为RM起作用了,RM赢得了+500赏金,直到我试图撰写祝贺的评论并发现我无法像往常一样浏览文本字段。)



回答:

我终于有机会在假期里进一步追求这一点。我发现了解决方案的麻烦。注意,这是在运行时动态更改Matlab GUI使用的Java类。它是完全不受支持的,并且可能非常脆弱。它可以在我的OS X Lion版本的Matlab(r2011a)上运行。

这是我对Swing / Matlab如何处理按键事件的了解:
  1. 按下按键。
  2. 搜索活动文本组件的inputMap以查看该击键是否存在绑定。
    • 如果有绑定到该键的动作,请分派该动作的actionPerformed方法
    • 如果存在与该击键相关联的字符串,请从文本组件的actionMap找到该动作,然后分派该动作的actionPerformed方法
  3. 无论如何 ,作为最后一步,调度在文本组件的Keymap.getDefaultAction()找到的操作。这就是问题所在。
该解决方案使用包装器覆盖了Keymap的默认操作,该包装器仅检查是否按下了修饰键。如果是这样,则将默默地忽略该操作。

步骤1:在Java中创建自定义TextAction来忽略修饰键

import javax.swing.text.TextAction; import javax.swing.Action; import java.awt.event.ActionEvent; public class IgnoreModifiedKeystrokesAction extends TextAction { private static final int ignoredModifiersMask = ActionEvent.CTRL_MASK | ActionEvent.ALT_MASK; private Action original; public IgnoreModifiedKeystrokesAction(Action act) { super((String)act.getValue("Name")); original = act; } public void actionPerformed(ActionEvent e) { if ((e.getModifiers() & ignoredModifiersMask) == 0) { /* Only dispatch the original action if no modifiers were used */ original.actionPerformed(e); } } public Action getOriginalAction() { return original; } } 编译为.jar :

javac IgnoreModifiedKeystrokesAction.java && jar cvf IgnoreModifiedKeystrokesAction.jar IgnoreModifiedKeystrokesAction.class 步骤2:在命令窗口和编辑器中覆盖MATLAB的默认Keymap处理程序(从MATLAB内部)

这里最难的部分是将Java句柄添加到命令窗口和编辑器。它取决于各个编辑器窗格的布局和类名。这可能会在Matlab版本之间发生变化。

javaaddpath('/path/to/IgnoreModifiedKeystrokesAction.jar') cmdwin = getCommandWindow(); editor = getEditor(); for t = [cmdwin,editor] defaultAction = t.getKeymap().getDefaultAction(); if ~strcmp(defaultAction.class(),'IgnoreModifiedKeystrokesAction') newAction = IgnoreModifiedKeystrokesAction(defaultAction); t.getKeymap().setDefaultAction(newAction); end end %% Subfunctions to retrieve handles to the java text pane elements function cw = getCommandWindow() try cw = handle(com.mathworks.mde.desk.MLDesktop.getInstance.getClient('Command Window').getComponent(0).getComponent(0).getComponent(0),'CallbackProperties'); assert(strcmp(cw.class(),'javahandle_withcallbacks.com.mathworks.mde.cmdwin.XCmdWndView')); catch %#ok cw_client = com.mathworks.mde.desk.MLDesktop.getInstance.getClient('Command Window'); cw = searchChildComponentsForClass(cw_client,'com.mathworks.mde.cmdwin.XCmdWndView'); end if isempty(cw) error('Unable to find the Command Window'); end end function ed = getEditor() try ed = handle(com.mathworks.mde.desk.MLDesktop.getInstance.getGroupContainer('Editor').getComponent(1).getComponent(0).getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(0).getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(0),'CallbackProperties'); assert(strcmp(ed.class(),'javahandle_withcallbacks.com.mathworks.mde.editor.EditorSyntaxTextPane')); catch %#ok ed_group = com.mathworks.mde.desk.MLDesktop.getInstance.getGroupContainer('Editor'); ed = searchChildComponentsForClass(ed_group,'com.mathworks.mde.editor.EditorSyntaxTextPane'); % TODO: When in split pane mode, there are two editor panes. Do I need % to change actionMaps/inputMaps/Keymaps on both panes? end if isempty(ed) error('Unable to find the Editor Window'); end end function obj = searchChildComponentsForClass(parent,classname) % Search Java parent object for a child component with the specified classname obj = []; if ~ismethod(parent,'getComponentCount') || ~ismethod(parent,'getComponent') return end for i=0:parent.getComponentCount()-1 child = parent.getComponent(i); if strcmp(child.class(),classname) obj = child; else obj = searchChildComponentsForClass(child,classname); end if ~isempty(obj) obj = handle(obj,'CallbackProperties'); break end end end 现在可以在使用选项键的标准首选项窗口中定义键绑定!

步骤3(可选):删除自定义操作

cmdwin = getCommandWindow(); editor = getEditor(); for t = [cmdwin,editor] defaultAction = t.getKeymap().getDefaultAction(); if strcmp(defaultAction.class(),'IgnoreModifiedKeystrokesAction') oldAction = defaultAction.getOriginalAction(); t.getKeymap().setDefaultAction(oldAction); end end javarmpath('/path/to/IgnoreModifiedKeystrokesAction.jar')

更多&回答...
poster 当前离线   回复时引用此帖
回复


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 20:30


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.