不可编辑的JEditorPane使用Enter键

时间:2015-10-23 22:34:39

标签: java swing jeditorpane

我有一个JDialog,其中包含JEditorPane,用于显示非用户可编辑的HTML内容,例如“帮助”和“发行说明”。

JDialog有一个"关闭"安装为默认按钮的按钮。

如果保留JEditorPane"可聚焦",则Page Up / Down键将滚动文档,但按" Enter"不会触发默认按钮。

另一方面,如果JEditorPane设置为不可聚焦,则Page Up / Down键不起作用,但按下" Enter"键会触发默认按钮,关闭对话框。

@SuppressWarnings("serial")
public class NoteViewer extends JFrame {

  public static void main(String[] args) throws IOException {
    final NoteViewer viewer = new NoteViewer(new URL("http://example.com/"));
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            viewer.setVisible(true);
        }
    });
  }

  public NoteViewer(URL url) throws IOException {
    super("Note Viewer");
    setSize(900, 200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JEditorPane notes = new JEditorPane(url);
    notes.setEditable(false);
    // notes.setFocusable(false);

    getContentPane().add(new JScrollPane(notes), BorderLayout.CENTER);

    JButton close = new JButton("Close");
    close.addActionListener(EventHandler.create(ActionListener.class, this, "dispose"));
    Box box = Box.createHorizontalBox();
    box.add(Box.createHorizontalGlue());
    box.add(close);
    getContentPane().add(box, BorderLayout.PAGE_END);

    getRootPane().setDefaultButton(close);
  }
}

取消注释notes.setFocusable(false)行以查看不同的行为。

我希望JEditorPane能够处理导航键击(例如Page Up / Down),但忽略(不消耗)"编辑"按键,例如Enter,以便根窗格将调用默认按钮。

经过多次黑客攻击和单步攻击后,我已经找到了我正在寻找的代码:

notes.getInputMap().put(
    KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
    "pressed");

但我担心这是相当脆弱的。所有平台都使用VK_ENTER来调用默认按钮吗?是否所有平台都使用"pressed"作为命令字符串来调用默认按钮?

最后,它是以错误的方式进行的:取代JEditorPane忽略Enter键并让处理在祖先中进行,这是显式处理回车键的JEditorPane,我错了。

不可编辑的JEditorPane不应捕获所有编辑键击(AZ,0-9,Enter,Delete等)并将其转换为警告音,而是将它们保持未处理状态以便父组件得到机会。如何通过一般的非击键输入映射方式实现这一目标?

2 个答案:

答案 0 :(得分:3)

  

所有平台都使用"按下"作为调用默认按钮的命令字符串?

这不是正在发生的事情。

您正在将Enter键映射到"已按下" JEdi​​torPane的行动。然而,没有"按下"操作,以便忽略Binding,并将事件传递到根窗格,在该窗格中使用默认按钮的Enter键绑定。

通常"无"用于表示您要忽略/删除绑定。有关详细信息,请查看How to Remove Bindings上Swing教程中的部分。

所以我会说你的解决方案是正确的,应该适用于所有平台。

您可能需要查看Key Bindings以查看显示每个组件的所有键绑定的程序。你会发现没有按下"行动。 JEdi​​torPane实际上使用" insert-break"映射到Action。

  

不可编辑的JEditorPane不应捕获所有编辑键击(A-Z,0-9,Enter,Delete等)并将其转换为警告音,

我没有发出哔哔声" a-z,0-9的问题。我确实有删除和退格键的问题。

我在Windows 7上使用JDK8_45。

也许您可以使用KeyEventDispatcher来阻止密钥的发送。也许您检查KeyEvent的来源,如果源是编辑器窗格,您只能让Enter键通过?可能还需要允许PageUp / PageDown事件,因此滚动将起作用。

查看Global Event Dispatching了解详情。

答案 1 :(得分:0)

我想我发现了一种更好的方法:将JEditorPane设置为不可编辑且不可调焦,JScrollPane可设置为焦点。

JEditorPane notes = new JEditorPane(url);
notes.setEditable(false);
notes.setFocusable(false);

JScrollPane scroller = new JScrollPane(notes);
scroller.setFocusable(true);
getContentPane().add(scroller, BorderLayout.CENTER);

Enter键将转发到默认按钮。退格,删除和朋友不会发出任何哔声。

修改 不允许选择和复制任何文本,因此可能不是最佳解决方案。