在Swing中模拟输入键(不使用机器人)

时间:2012-03-14 23:37:33

标签: java swing keyboard-events

所以我正在尝试编写一个JButton,它在按下时会像输入键一样。它必须能够欺骗一个焦点的JTextField来调用它的动作监听器。它不能使用机器人框架,因为这将使每个程序认为输入被按下,这是一个问题。

这是背景故事:

我有一个程序(用Swing编写),允许有人在键入数据后点击输入,在许多文本字段和其他内容中输入数据。它很棒。

然而,大多数使用它的人正在同时使用第二个程序,它会自动侦听回车键并关闭机器人(对于那些熟悉FIRST机器人的人,我说的是SmartDashboard和司机站)。对此有不少抱怨。人们希望在不禁用机器人的情况下输入数据。事实证明,SmartDashboard(人们想要点击的程序)允许自定义挥杆组件随之运行。

3 个答案:

答案 0 :(得分:4)

不完全确定我是否正确理解您的要求(如果没有,将删除)...

您可以手动将事件分派给要解决的任何组件。在想要派遣到focusOwner

的情况下
  • 通过查询KeyboardFocusManager
  • 找到focusOwner
  • 使用focusOwner作为发件人
  • 创建一个keyEvent
  • 将该事件发送到focusOwner

类似的东西:

Action action = new AbstractAction("fake enter") {

    @Override
    public void actionPerformed(ActionEvent e) {
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        Component comp = manager.getFocusOwner();
        KeyEvent event = new KeyEvent(comp, 
                KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, 
                KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED);
        comp.dispatchKeyEvent(event);
    }
};
JButton button = new JButton(action);
button.setFocusable(false);

Action textAction = new AbstractAction("text") {

    @Override
    public void actionPerformed(ActionEvent e) {
        LOG.info("I'm the text action" + ((Component) e.getSource()).getName());
    }
};

JComponent comp = Box.createVerticalBox();
for (int i = 0; i < 5; i++) {
    JTextField field = new JTextField(20);
    field.setName(": " + i);
    field.setAction(textAction);
    comp.add(field);
}
comp.add(button);

修改

添加了一些实际玩它的行(@Joe评论它不起作用)。单击该按钮会触发焦点textField的操作(此处只是打印出字段的名称)本地上下文是vista和jdk6u27。

答案 1 :(得分:2)

您可以在框架上尝试getRootPane().setDefaultButton()。有一个例子here

答案 2 :(得分:2)

使用焦点抓取元素并手动调度enter事件并不是很有效,但是因为我只想实现各种JTextField,我提出了类似的解决方案:

addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        if (focusOwner instanceof JTextField) {
            ((JTextField) focusOwner).postActionEvent();
        }
    }   
});

感谢您指出我正确的方向。