我(使用Netbeans中的GUI设计器)设计了一个带有两个单选按钮和一个数字微调器的小对话框。
- 如果在焦点位于某个单选按钮上时按Enter键,则对话框将正确关闭,但如果焦点位于微调器上,则必须用Tab键远离微调器才能使用Enter键。
- 如何指示对话框Enter的真正含义是"接受并关闭"
- 或者,我如何指示(每个)输入字段将Enter中继到"接受并关闭"处理程序
- 同样,即使焦点在微调器(或其他字段)上,我如何指示对话框Esc的真正含义是"取消并关闭"
如何指示(每个)输入字段将Enter中继到"接受并关闭"处理程序?
最简单的方法是在对话框上定义一个"默认按钮"。然后,当按下Enter时,默认按钮将被激活。查看Enter键和按钮以了解不同的方法。
我该如何指示对话框Esc的真正含义是"取消并关闭"
使用Key Bindings
调用"取消"按钮的"操作"。
首先定义按钮要使用的Action
:
public class CancelAction extends AbstractAction
{
public CancelAction()
{
super("Cancel");
putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C) );
}
@Override
public void actionPerformed(ActionEvent e)
{
Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if (window != null)
{
WindowEvent windowClosing = new WindowEvent(window, WindowEvent.WINDOW_CLOSING);
window.dispatchEvent(windowClosing);
}
}
}
然后将Action
添加到按钮中,以便用户可以使用鼠标:
CancelAction cancelAction = new CancelAction();
cancelButton.setAction( cancelAction );
dialog.add(cancelButton);
现在,您可以使用键绑定将Escape键绑定到CancelAction,这样用户就可以使用键盘:
KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE");
getRootPane().getActionMap().put("ESCAPE", cancelAction);
我怀疑我出现问题的原因是微调器实际上是一个复合控件,而文本(嗯,数字)字段就是其中的一个组件。因此我需要将事件连接到该子组件,而不是连接到微调器本身:
// Make Ok/Cancel work when JSpinner has focus
getSpinnerField(jSpinnerOffset).addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
doOk();
}
});
其中"getSpinnerField()"只是私有方法中的简写:
private JFormattedTextField getSpinnerField(JSpinner spinner) {
return ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
}
这样,Esc键就可以自动关闭对话框。