我有一个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等)并将其转换为警告音,而是将它们保持未处理状态以便父组件得到机会。如何通过一般的非击键输入映射方式实现这一目标?
答案 0 :(得分:3)
所有平台都使用"按下"作为调用默认按钮的命令字符串?
这不是正在发生的事情。
您正在将Enter键映射到"已按下" JEditorPane的行动。然而,没有"按下"操作,以便忽略Binding,并将事件传递到根窗格,在该窗格中使用默认按钮的Enter键绑定。
通常"无"用于表示您要忽略/删除绑定。有关详细信息,请查看How to Remove Bindings上Swing教程中的部分。
所以我会说你的解决方案是正确的,应该适用于所有平台。
您可能需要查看Key Bindings以查看显示每个组件的所有键绑定的程序。你会发现没有按下"行动。 JEditorPane实际上使用" 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键将转发到默认按钮。退格,删除和朋友不会发出任何哔声。
修改强> 不允许选择和复制任何文本,因此可能不是最佳解决方案。