键绑定和按住键

时间:2012-08-31 22:18:42

标签: java swing jtextarea key-bindings keystrokes

我为JTextArea组件创建了一个键绑定。调用时,它会创建一个自身的新实例并将焦点设置为它。

如果你按住enter(调用键绑定),我的程序将开始吐出一堆JTextArea实例。

有没有办法强制用户按下输入againg来创建新实例?

我是否可以切换到KeyListeners,或者是否有使用键绑定的方式?

3 个答案:

答案 0 :(得分:4)

您在设置输入地图时指定KeyStroke仅触发按键释放

请参阅KeyStroke getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)

答案 1 :(得分:2)

使用键绑定来实现它的方法是有两个动作:

  • 创建组件的操作绑定到按下的enter,它在插入组件时自行禁用
  • 再次启用操作的操作将绑定到已发布的回车

一些代码:

// 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);

请注意,相同的操作实例会注册到所有组件,因此哪个具有焦点(并最终再次启用创建)无关紧要

答案 2 :(得分:0)

这是我使用的代码,仅在第一次按下某个键时才运行操作:

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;