【问题标题】:JTextComponent KeymapJTextComponent 键盘映射
【发布时间】:2012-08-15 16:24:41
【问题描述】:

我需要创建一个从JTextComponent(实际上是JTextPane)派生的类,其中至少有一个默认键映射被更改。也就是说,在我的特殊 JTextPane 中,我希望 ">" 击键来执行操作,而不是将该字符添加到文本窗格中,因为默认情况下会处理所有可打印的键入字符。

为了阻止正常行为,有以下 API:

  • JTextComponent.getKeymap()
  • Keymap.addActionForKeyStroke()
  • JTextComponent.setKeymap()

但是,我发现尽管这些方法不是静态的,但它们确实会影响我的应用程序中所有 JTextComponents 使用的键盘映射。没有可以克隆 Keymap 的简单机制,这可能会解决问题,或者我错过了什么。

我所追求的是一种为我的JTextPane 类而不是所有JTextComponent 派生类更改键盘映射的方法。

或者我应该去别处寻找?

【问题讨论】:

  • 这是一个很棒的问题,做得很好。虽然它没有直接回答问题,但请查看stackoverflow.com/questions/9610386/… 以了解其他人在类似情况下所做的示例。艾默里克走在正确的轨道上

标签: java swing keymapping jtextcomponent


【解决方案1】:

恕我直言,这有点难以理解,但答案在这里: Using the Swing Text Package by Tim Prinzing

本文的作者 Tim Prinzing,根据源代码,我相信他也是 JTextComponent 的作者,提供了一个我将评论的示例:

      JTextField field = new JTextField();
// get the keymap which will be the static default "look and feel" keymap
      Keymap laf = field.getKeymap();
// create a new keymap whose parent is the look and feel keymap
      Keymap myMap = JTextComponent.addKeymap(null, laf);
// at this point, add keystrokes you want to map to myMap
      myMap.addActionForKeyStroke(getKeyStroke(VK_PERIOD, SHIFT_DOWN_MASK), myAction); 
// make this the keymap for this component only.  Will "include" the default keymap
      field.setKeymap(myMap);

我的错误是将我的击键添加到 getKeymap 返回的键映射中,而不是让它给孩子。恕我直言,名称 addKeymap() 令人困惑。应该是 createKeymap()。

【讨论】:

  • 但是,但是,但是……我本来以为当我的按键被按下时,按键处理(参见上面提到的文章中的图表)找到我的按键并执行操作(这部分有效很好),它将消耗关键事件。这不会发生!相反,它还会将其打印在屏幕上。通过登录 Key Listener,我可以看到该事件仍然存在。但是,我在操作中得到的只是一个 ActionEvent,不能被消费!
  • 链接已烂,无法访问。由于您没有写页面名称或类似名称,我不知道如何搜索它。你认为你能找到页面的新位置,或者记得页面是如何命名的吗?
  • @Suma - 这并不容易,但我找到了谷歌的东西:“myMap Prinzing”。这让我找到了comp.nus.edu.sg/~cs3283/ftp/Java/swingConnect/text/text/…。并且文章的标题是“使用 Swing 文本包”。找不到它的任何其他副本。看起来甲骨文摆脱了它。
【解决方案2】:

我会改用特定的Document,尤其是如果您希望您的映射仅对实例有效而不是全局有效。

以下是捕获键并执行适当操作的示例:

JFrame f = new JFrame();

StyledDocument d = new DefaultStyledDocument() {
   @Override
   public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
      if (">".equals(str)) {
         // Do some action
         System.out.println("Run action corresponding to '" + str + "'");
      } else {
         super.insertString(offs, str, a);
      }
   }
};

JTextPane t = new JTextPane(d);
f.add(t);

【讨论】:

  • 我会使用个人使用的 DocumentFilter,但我认为你在正确的轨道上。我个人有点担心在过滤器上附加某种动作,但这只是我;)
猜你喜欢
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
  • 2010-10-18
  • 1970-01-01
相关资源
最近更新 更多