简体   繁体   English

不可编辑的JEditorPane消耗Enter键

[英]Non-editable JEditorPane consumes Enter key

I have an JDialog containing a JEditorPane for showing non-user-editable HTML content, such as Help and Release Notes. 我有一个包含JEditorPaneJDialog ,用于显示非用户可编辑的HTML内容,例如帮助和发行说明。

The JDialog has a "Close" button that is installed as the default button. JDialog有一个“关闭”按钮,作为默认按钮安装。

If the JEditorPane is left "focusable", then the Page Up/Down keys will scroll through the document, but pressing "Enter" does not fire the default button. 如果JEditorPane保持“可聚焦”状态,则Page Up / Down键将滚动文档,但按“Enter”不会触发默认按钮。

On the other hand, if the JEditorPane is set non-focusable, then Page Up/Down keys do not work, but pressing the "Enter" key does fire the default button, closing the dialog. 另一方面,如果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);
  }
}

Uncomment the notes.setFocusable(false) line to see the different behavior. 取消注释notes.setFocusable(false)行以查看不同的行为。

I would like the JEditorPane to process the navigation keystrokes (such as Page Up/Down), but ignore (not consume) the "editing" keystrokes, such as Enter, so that the Root Pane will invoke the default button. 我希望JEditorPane处理导航键击(例如Page Up / Down),但忽略(不消耗)“编辑”键击,例如Enter,以便Root Pane将调用默认按钮。

After much hacking and single-stepping, I've got the behaviour I'm looking for with this code: 经过多次黑客攻击和单步攻击后,我得到了我正在寻找的代码:

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

but I am concerned that it is rather fragile. 但我担心这是相当脆弱的。 Do all platforms use VK_ENTER to invoke the default button? 所有平台都使用VK_ENTER来调用默认按钮吗? Do all platforms use "pressed" as the command-string to invoke the default button? 是否所有平台都使用"pressed"作为命令字符串来调用默认按钮?

Finally, it is going about it the wrong way: instead of the JEditorPane ignoring the Enter key and letting the processing happen in an ancestor, this is the JEditorPane explicitly handling the enter key, which strikes me as wrong. 最后,它是错误的方式:而不是JEditorPane忽略Enter键并让处理发生在祖先,这是JEditorPane显式处理输入键,这让我觉得错误。

A non-editable JEditorPane should not capture all the editing keystrokes (AZ, 0-9, Enter, Delete, etc.) and transform them into a warning beep, but rather leave them unhandled so that parent components get a chance. 不可编辑的JEditorPane不应捕获所有编辑键击(AZ,0-9,Enter,Delete等)并将它们转换为警告蜂鸣声,而是将它们保持未处理状态,以便父组件有机会。 How can this be achieved in a general, non keystroke-by-keystroke input map fashion? 如何通过一般的非击键输入映射方式实现这一点?

Do all platforms use "pressed" as the command-string to invoke the default button? 是否所有平台都使用“pressed”作为命令字符串来调用默认按钮?

That is not what is happening. 这不是正在发生的事情。

You are mapping the Enter key to the "pressed" Action of the JEditorPane. 您正在将Enter键映射到JEditorPane的“按下”操作。 However, there is no "pressed" Action so the Binding is ignored and the event is passed up to the root pane where the Enter key binding for the default button is used. 但是,没有“按下”操作,因此忽略Binding,并将事件传递到根窗格,在该窗格中使用默认按钮的Enter键绑定。

Normally "none" is used to indicate you want to ignore/remove the binding. 通常,“none”用于表示您要忽略/删除绑定。 Check out the section from the Swing tutorial on How to Remove Bindings for more information. 有关更多信息,请查看Swing教程中有关如何删除绑定的部分。

So I would say you solution is correct and should work on all platforms. 所以我会说你的解决方案是正确的,应该适用于所有平台。

You may want to check out Key Bindings for a programs that displays all the key bindings for each component. 你可能想看看键绑定用于显示所有每个组件的按键绑定一个程序。 You will see that there is no "pressed" action. 您将看到没有“按下”动作。 JEditorPane actually uses "insert-break" to map to the Action. JEdi​​torPane实际上使用“插入 - 中断”来映射到Action。

A non-editable JEditorPane should not capture all the editing keystrokes (AZ, 0-9, Enter, Delete, etc.) and transform them into a warning beep, 不可编辑的JEditorPane不应捕获所有编辑键击(AZ,0-9,Enter,Delete等)并将其转换为警告蜂鸣声,

I don't have a "beeping" problem with az, 0-9. 我没有az,0-9的“嘟嘟”问题。 I do have a problem with the delete and backspace keys. 我确实有删除和退格键的问题。

I'm using JDK8_45 on Windows 7. 我在Windows 7上使用JDK8_45。

Maybe you can prevent the dispatching of keys by using a KeyEventDispatcher . 也许你可以通过使用KeyEventDispatcher来阻止密钥的调度。 Maybe you check the source of the KeyEvent and if the source is the editor pane you only let the Enter key through? 也许您检查KeyEvent的来源,如果源是编辑器窗格,您只能让Enter键通过? Might also need to allow the PageUp/PageDown events so scrolling will work. 可能还需要允许PageUp / PageDown事件,因此滚动将起作用。

Check out Global Event Dispatching for more information. 查看全球事件调度以获取更多信息。

I think I just found a better way: set the JEditorPane as not editable and not focusable, and the JScrollPane as focusable. 我想我刚刚找到了一个更好的方法:将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);

The Enter key is forwarded to the default button. Enter键将转发到默认按钮。 Backspace, delete and friends don't generate any beeps. 退格,删除和朋友不会产生任何哔哔声。

Edit: Doesn't allow selecting and copying of any text, so perhaps not the best solution. 编辑:不允许选择和复制任何文本,因此可能不是最佳解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM