2012-03-14 71 views
4

因此,我正在尝试编写一个JButton,它在按下时将像输入键一样工作。它必须能够欺骗焦点中的JTextField来调用其动作侦听器。它不能使用机器人框架,因为这会让每个程序都认为输入被按下,这是一个问题。在Swing中模拟输入键(不使用机器人)

这里是背景故事:

我有一个程序(用Swing编写),它允许一个人通过点击在数据输入后进入,进入许多文本框和其他东西的数据。它效果很好。

但是,大多数使用它的人同时使用第二个程序,它会自动侦听输入密钥并关闭机器人(对于那些熟悉FIRST机器人的人,我正在谈论SmartDashboard和Driver Station)。对此有不少抱怨。人们希望输入数据而不禁用机器人。事实证明,SmartDashboard(人们想要击中的程序)允许自定义摆动组件与其一起运行。

+0

是否有可能使用与输入不同的组合键? Ctrl-S如果想要考虑填充字段为“保存”输入? – Thomas 2012-03-14 23:49:25

+0

这不是不可能的,但它肯定不是优选的。我也考虑过有选项卡(即当你失去焦点时)保存数据,但我真的想保留它作为输入键。 – Joe 2012-03-14 23:52:38

回答

4

不能完全肯定,如果我理解正确你的要求(如不将删除此)...

您可以手动分派事件到要解决任何组件。在希望派遣到focusOwner

  • 的情况下,通过查询的KeyboardFocusManager
  • 创建具有focusOwner的KeyEvent发件人
  • 分派该事件的focusOwner

东西找到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评论它不工作)。单击该按钮将触发焦点文本字段的操作(此处仅显示字段名称)。本地上下文是vista和jdk6u27。

+0

反思,你可能是对的; +1为相反的“行动”。 – trashgod 2012-03-15 18:09:14

+0

我能够得到这个回复我想要的任何信件(比如,如果我发送“a”字符,将会输入“a”),但我无法完全使用回车键。 – Joe 2012-03-15 18:42:29

+0

@Joe嗯...这很奇怪:我的答案中的代码片段按原样触发textField的动作(当然,在发布之前尝试过):什么是您的操作系统和jdk版本? – kleopatra 2012-03-16 09:24:38

2

拼抢元素与对焦和手动调度enter事件也不太工作,但因为我只是想实现不同的JTextField,我想出了一个类似的解决方案:

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

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

+0

hach​​ ..编辑我的之前没有看到这个:-)好的你找到了你的解决方案。仍然认为它很奇怪,我的工作并不适合你的情况。 – kleopatra 2012-03-16 09:33:14