【问题标题】:which component handles arrow KeyEvents when JTextPane is embedded in JScrollPane?当 JTextPane 嵌入到 JScrollPane 中时,哪个组件处理箭头 KeyEvents?
【发布时间】:2012-09-19 21:11:27
【问题描述】:

好的,我们又来了。史蒂夫必须编写另一组非标准击键。 我们在 JScrollPane 中嵌入了一个可编辑的 JTextPane。此窗格正确处理向上和向下箭头键,但我不知道如何。如果我能弄清楚如何,我可以实现我需要实现的非标准事物。

具体来说,因为 PageDown 键被全局映射到执行另一个功能,我们不执行 PageUp、PageDown、Ctrl-PageUp 和 Ctrl-PageDown 的默认操作。相反,我们希望将这些功能映射到移动的箭头键,而不是数字键盘上的那些。

具体在 JScrollPane 类的祖先输入映射 ((InputMap)UIManager.get("ScrollPane.ancestorInputMap");) 我们添加

  • 向下移动箭头键指向祖先输入映射 “向下滚动”操作
  • 向上移动箭头键指向 Ancestor 输入映射,指向 “向上滚动”操作
  • 将左箭头键移到 Ancestor 输入映射,指向 “scrollHome”操作
  • 将右箭头键移到 Ancestor 输入映射,指向 “scrollEnd”动作

这些按键都没有任何作用。我什至重写了 JComponent 的 processKeyEvent() 和 processKeyBinding() 方法来记录发生的事情,我发现这些击键永远不会触发这些方法。此外,普通的标准向上箭头和向下箭头击键不会触发这些方法,即使这些击键确实有效。

所以很明显,其他东西正在处理这些击键。但那是什么组件? 是的,当我尝试这个时,文本窗格确实有焦点。

【问题讨论】:

  • 尽快发布SSCCE 以获得更好的帮助。
  • 也许,但总的来说,在正常的 Swing 中,与我可怕的混蛋版本相反,哪个组件处理箭头键?是滚动条、滚动窗格还是文本窗格?
  • 另见Key Bindings,其中列出了每个 L&F 的默认值。
  • 睡觉时间,关于具体 L&F 的键和差异的精彩评论
  • @trashgod - 是的,在这种情况下,键绑定始终是我的第一站,事实上我已经去过那里。你认为我怎么知道输入地图和动作的名称?但在这种情况下,这并没有回答我的问题。

标签: java swing jscrollpane key-bindings


【解决方案1】:
  • Steve 的参考版本 :-)

  • 杜也喜欢这个论坛,

  • SSCCE 可以为第二侧的志愿者打开任何门。不是吗

【讨论】:

  • 部分问题是,这些命名的操作实际上是做什么的?在滚动窗格页面中,我们将 CTRL_PAGE_UP 映射到“scrollLeft”,将 CTRL_PAGE_DONN 映射到“scrollRight”。这有点好奇。这是否意味着转到文档的顶部或底部?还有“scrollHome”和“scrollEnd”动作。我已经尝试将这两个集合映射到我的 Shift-Right 和 Shift-Left 键(在文本窗格中禁用它们之后)并且两者都没有。但是相同的机制适用于 Shift-Up 和 Shift-Down。很好奇。
  • 好吧,深入研究 Swing 源代码,很明显我想要“scrollHome”和“scrollEnd”,而不是“scrollLeft”和“scrollRight”。但是,无论如何,它们都不起作用。
  • @Steve Cohen 查看 StanislavL 的回答
【解决方案2】:

正如 mKorbel 正确显示的那样,有一个动作“向上翻页”和“向下翻页”(参见第三个屏幕)。所以只需使用 ActionMap 并将操作替换为您的操作。

【讨论】:

  • page-up 和 page-down 不是我想要的。我想要让插入符号保持独立的滚动动作,而不是插入符号移动动作,这就是我认为向上翻页和向下翻页的动作,但即使这些动作不移动插入符号,我已经得到了我需要的东西来自 ScrollPane 的 scrollUp 和 scrollDown 动作。我无法工作的是“scrollHome”和“scrollEnd”动作。谢谢
【解决方案3】:

好的,trashgod 基本上是对的。解决方案是对操作使用 KeyBindings 名称。找到正确答案的延迟是由于一些杂散的代码正在撤消其他地方的映射。

更具体地说,我们禁用 JTextPane 中的默认击键,然后将它们添加到 Scroll Pane 的输入映射,映射到它们的新操作。

在 TextPane 构造函数中

...
        disableAction("caret-down"); // down arrow
        disableAction("caret-up");   // up arrow
        disableAction("selection-backward"); // shift-left-arrow
        disableAction("selection-forward");  // shift-right-arrow
        disableAction("selection-up");  //shift-up-arrow
        disableAction("selection-down"); // shift-down-arrow

    }

    private void disableAction(String name) {
        Action a = getActionMap().get(name);
        if (a != null) {
            a.setEnabled(false);
        }
    }

在滚动窗格中

import static javax.swing.KeyStroke.getKeyStroke;
import static java.awt.event.KeyEvent.*;
...
    private void remapShiftedArrowKeys() {
        InputMap map = (InputMap)UIManager.get("ScrollPane.ancestorInputMap");
        map.put(getKeyStroke(VK_DOWN, SHIFT_DOWN_MASK), "scrollDown");
        map.put(getKeyStroke(VK_UP, SHIFT_DOWN_MASK), "scrollUp");
        map.put(getKeyStroke(VK_LEFT, SHIFT_DOWN_MASK), "scrollHome");
        map.put(getKeyStroke(VK_RIGHT, SHIFT_DOWN_MASK), "scrollEnd");
    }

请注意,我们不必映射移动的 Up 和 Down 键,因为 JScrollPane 已经使用这些键完成了我们想要的操作。从 JTextPane 中取消映射它们就足够了。而其他四个击键是完全非标准的,也必须在滚动窗格中重新映射。

感谢您的帮助!

哦,实际的答案是 JTextPane 通常当然会处理这些箭头键。为了做我想做的事,我必须打败它并在滚动窗格中适当地映射,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多