Java 在MATLAB for Mac中启用选项键快捷方式
自R2009b以来,MATLAB已经通过它的。这对于在Mac上使用命令和控制自定义快捷方式非常有效 不幸的是,这些键绑定似乎无法覆盖MATLAB的内置字符映射。例如,如果我将option-f定义为Java 在MATLAB for Mac中启用选项键快捷方式,java,swing,matlab,keyboard-shortcuts,Java,Swing,Matlab,Keyboard Shortcuts,自R2009b以来,MATLAB已经通过它的。这对于在Mac上使用命令和控制自定义快捷方式非常有效 不幸的是,这些键绑定似乎无法覆盖MATLAB的内置字符映射。例如,如果我将option-f定义为cursornext word(ala emacs),则它接受绑定。点击组合键确实会将光标正确地移动到下一个单词,但它会额外打印ƒ字符!我相信这是来自角色映射(可能与输入映射相反?)。也无法覆盖此行为 我无意中发现了给我希望的东西。简而言之,他定义了一个Java类,可以处理键盘事件并用其他击键输入替换它
cursornext word
(ala emacs),则它接受绑定。点击组合键确实会将光标正确地移动到下一个单词,但它会额外打印ƒ
字符!我相信这是来自角色映射(可能与输入映射相反?)。也无法覆盖此行为
我无意中发现了给我希望的东西。简而言之,他定义了一个Java类,可以处理键盘事件并用其他击键输入替换它们。但是,该解决方案只能在Windows上按规定工作。要在Mac上运行,需要进行以下修改:
我需要将按键代码更改为重新映射,以便在字符串中“按下”,如下所示:
map = {
'$' '^'
'#' char(181) % might be useful for text formatting
};
致:
不幸的是,在运行代码后,按option-f会产生光标下一个单词
和ƒ
字符,就像前面一样。但是,如果我从首选项中禁用下一个单词的光标
绑定,那么我将同时获得和^
!事实上,即使我使用了一个简单的动作,比如按下F,KeyReplacementAction也不会取代动作,而是增强了动作。这似乎是OS X上的MATLAB独有的行为
似乎我只是没有覆盖正确的键映射。我已经尝试过深入研究Java运行时,但是我对事件调度模型还不够熟悉,不知道下一步该去哪里。也许是Java操作系统级密钥映射中的某些东西
编辑:此后我又进行了一些挖掘。似乎Mac版的MATLAB没有正确地尊重keyEvent的“消费”属性。我可以将KeyReplacementAction附加到
inputMap
或keymap
,在这两种情况下,我都会增加键绑定而不是替换它。我使用反射来“取消”AWTEvents的consume()
方法,但效果与以前相同
在堆栈跟踪之后,keyEvent似乎正在落入javax.swing.KeyboardManager
的实例。看起来我应该能够在KeyboardManager中解除按键绑定,但是我不知道如何从我拥有的MATLAB句柄访问该实例。也许更熟悉Swing的事件模型和Java调试器的人可以走得更远
编辑2::的答案促使我研究X11的关键地图。几点注意:
- Matlab似乎不尊重
或任何当前加载的modmap李>~/.Xmodmap
- 如果环境变量在启动时存在,Matlab将使用环境变量
。否则,它将从$XKEYSYMDB
加载它$MATLAB/X11/app defaults/XKeysymDB
- 整个
目录看起来非常有趣;也许那里的黑客可以让这一切顺利$MATLAB/X11/app defaults/
- Mac上的X11密钥映射在哪里?MATLAB如何切换到国际键盘布局
编辑3:人力资源管理,我认为X11是一种误导
lsof-cmab
显示它正在访问/System/Library/Keyboard Layouts/AppleKeyboardLayouts.bundle
。现在正在做这件事
编辑4:MATLAB确实使用了系统键盘布局。我创建了一个没有任何绑定的。这似乎是可行的-MATLAB的行为是正确的。不幸的是,它还破坏了我在所有其他程序中的自定义Cocoa键绑定。很近,但没有雪茄。(事实上,距离足够近,R.M.赢得了+500赏金是因为一个简单的想法,它已经起作用了……直到我试图撰写我的祝贺性评论,发现我无法像往常一样浏览文本字段。)我没有一个完整的解决方案,但我有一些可能的方法,如果你还没有看的话,你可以尝试 MATLAB的键盘密码保存在
/Users/$user/.MATLAB/$version/$name\u keybindings.XML
中的XML
文件中,其中$user
是您的用户名,$version
是MATLAB的版本,$name
是您保存的任何键绑定。看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<CustomKeySet derivedfrom="Mac" modifieddefault="false">
<Context id="Global">
<Action id="eval-file">
<Stroke alt="on" code="VK_ENTER" meta="on" sysctrl="on"/>
</Action>
<stuff here /stuff>
</Context>
</CustomKeySet>
,这是Mac电脑的键盘布局编辑器。在S.O.和相关网站上出现了一些问题,他们使用Ukelle来、、等。您可以尝试重新定义键盘布局以禁用Opt-f
(除非您需要MATLAB之外的特定字符),这应该可以解决问题
最后,当问题是“我该怎么做?”时,我并不是说“你应该做些别的事情”,但总的来说,对于Mac,我发现将Ctrl
映射到windows/emacsAlt
快捷方式比Opt
更容易。大多数情况下,出于同样的原因,也因为Opt
离我笔记本电脑上的Cmd
键太近了,以至于我的胖手指在无意中按了Cmd
(这从来不会发生相反的情况)。作为一个丑陋的解决办法:我没有在MacOS上工作,所以我进入了“可能是一个好提示”:在可以捕获X事件并按需执行命令的Xexist工具下,谷歌给出了一个快速的例子,例如xkbevd也存在于MacOS下(我假设您提到的java工具也有类似的功能)。在这里,您可以捕获ctrl-f并用ctrl-f backspace替换它,从而否定额外的字符。
(非常难看,它打破了matlab之外的代码)
如果您不想更改命令行上的行为,但只想在编辑器中更改,则可以使用另一个选项
<?xml version="1.0" encoding="utf-8"?>
<CustomKeySet derivedfrom="Mac" modifieddefault="false">
<Context id="Global">
<Action id="eval-file">
<Stroke alt="on" code="VK_ENTER" meta="on" sysctrl="on"/>
</Action>
<stuff here /stuff>
</Context>
</CustomKeySet>
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;
}
}
javac IgnoreModifiedKeystrokesAction.java && jar cvf IgnoreModifiedKeystrokesAction.jar IgnoreModifiedKeystrokesAction.class
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<CTCH>
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<CTCH>
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
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')