我为 JTextArea 组件创建了一个键绑定。当被调用时,它会创建一个自己的新实例并将焦点放在它上面。
如果您按住回车键(调用键绑定),我的程序将开始吐出一堆 JTextArea 实例。
有没有办法强制用户再次按回车键来创建一个新实例?
我是切换到 KeyListeners 还是有键绑定的方法?
我为 JTextArea 组件创建了一个键绑定。当被调用时,它会创建一个自己的新实例并将焦点放在它上面。
如果您按住回车键(调用键绑定),我的程序将开始吐出一堆 JTextArea 实例。
有没有办法强制用户再次按回车键来创建一个新实例?
我是切换到 KeyListeners 还是有键绑定的方法?
KeyStroke
您在设置输入映射时指定仅在按键释放时触发
参见 KeyStroke getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
使用键绑定的方法是执行两个操作:
一些代码:
// the action to create the component
public static class CreateAction extends AbstractAction {
private Container parent;
private Action enableAction;
public CreateAction(Container parent) {
this.parent = parent;
enableAction = new EnableAction(this);
}
@Override
public void actionPerformed(ActionEvent e) {
setEnabled(false);
Component field = createTextField();
parent.add(field);
parent.revalidate();
field.requestFocus();
}
int count;
private Component createTextField() {
// just for fun counting the fields we create
JTextField field = new JTextField("field: " + count++, 20);
field.getInputMap().put(KeyStroke.getKeyStroke("ENTER"),
"createComponent");
field.getActionMap().put("createComponent", this);
field.getInputMap().put(KeyStroke.getKeyStroke("released ENTER"),
"enableCreation");
field.getActionMap().put("enableCreation", enableAction);
return field;
}
}
// the action that enables another
public static class EnableAction extends AbstractAction {
Action toEnable;
public EnableAction(Action toEnable) {
this.toEnable = toEnable;
}
@Override
public void actionPerformed(ActionEvent e) {
toEnable.setEnabled(true);
}
}
// usage
final JComponent parent = new JPanel(new MigLayout("wrap"));
// here I'm lazy and let the action create the very first component as well
add.actionPerformed(null);
add.setEnabled(true);
请注意,相同的操作实例已注册到所有组件,因此哪个具有焦点并不重要(并最终再次启用创建)
这是我使用的代码,仅在第一次按下键时才运行操作:
private void registerKeyBindings(final JFrame frame) {
var inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(KeyCode.G.getInputEventCode(), 0, false), "g_down");
inputMap.put(KeyStroke.getKeyStroke(KeyCode.G.getInputEventCode(), 0, true), "g_up");
frame.getRootPane().getActionMap().put("g_down", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
if (gDown) return;
gDown = true;
// put your custom key-down-action code here
}
});
frame.getRootPane().getActionMap().put("g_up", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
gDown = false;
}
});
}
Boolean gDown = false;