MATLAB爱好者论坛-LabFans.com

MATLAB爱好者论坛-LabFans.com (https://www.labfans.com/bbs/index.php)
-   资料存档 (https://www.labfans.com/bbs/forumdisplay.php?f=72)
-   -   在Mac版MATLAB中启用选项键快捷方式 (https://www.labfans.com/bbs/showthread.php?t=26571)

poster 2019-12-14 20:13

在Mac版MATLAB中启用选项键快捷方式
 
从R2009b开始,MATLAB通过其[URL="http://blogs.mathworks.com/desktop/2009/09/28/configurable-keyboard-shortcuts-have-arrived/"]Keyboard Shortcuts Preferences[/URL]拥有了可定制的键盘快捷[URL="http://blogs.mathworks.com/desktop/2009/09/28/configurable-keyboard-shortcuts-have-arrived/"]键[/URL] 。这对于在Mac上使用命令和控制来自定义快捷方式非常有效。

不幸的是,这些键绑定似乎无法覆盖MATLAB的内置字符映射。例如,如果我将option-f定义为cursor-next-word (la emacs),则它接受绑定。击中组合键,光标不会正确地移动到下一个词,但它另外打印茠字符!我相信这是从字符映射表(也许与输入映射表相反?)中获得的。 [URL="http://www.mathworks.com/matlabcentral/fileexchange/24615-editormacro-assign-a-macro-to-a-keyboard-key-stroke-in-the-matlab-editor-and-command-window"]EditorMacro[/URL]和[URL="http://www.mathworks.com/matlabcentral/fileexchange/25089"]KeyBindings[/URL]均不能覆盖此行为。

我[URL="https://stackoverflow.com/questions/1759413/how-do-i-make-a-character-in-matlab/1786487#1786487"]从一个与切向相关的问题中[/URL]偶然发现了[URL="https://stackoverflow.com/questions/1759413/how-do-i-make-a-character-in-matlab/1786487#1786487"]这个答案,[/URL]这给了我希望。简而言之,他定义了一个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绑定,那么我会[B]同时[/B]获得茠和^ !确实,即使我使用了一个简单的动作(例如pressed F ,KeyReplacementAction也不代替该动作,而是对其进行了[I]增强[/I] 。似乎此行为是OS X上的MATLAB特有的。

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

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

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

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



[B]回答:[/B]

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

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

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

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 [B]步骤2:在命令窗口和编辑器中覆盖MATLAB的默认Keymap处理程序(从MATLAB内部)[/B]

这里最难的部分是将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 现在可以在使用选项键的标准首选项窗口中定义键绑定!

[B]步骤3(可选):删除自定义操作[/B]

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')

[url=https://stackoverflow.com/questions/5274998]更多&回答...[/url]


所有时间均为北京时间。现在的时间是 09:01

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