Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在MATLAB for Mac中启用选项键快捷方式_Java_Swing_Matlab_Keyboard Shortcuts - Fatal编程技术网

Java 在MATLAB for Mac中启用选项键快捷方式

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类,可以处理键盘事件并用其他击键输入替换它

自R2009b以来,MATLAB已经通过它的。这对于在Mac上使用命令和控制自定义快捷方式非常有效

不幸的是,这些键绑定似乎无法覆盖MATLAB的内置字符映射。例如,如果我将option-f定义为
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似乎不尊重
    ~/.Xmodmap
    或任何当前加载的modmap
  • 如果环境变量在启动时存在,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/emacs
Alt
快捷方式比
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')