简体   繁体   中英

Simulating enter key in Swing (without using Robot)

So I'm trying to write a JButton that will act like an enter key when pressed. It must be able to fool a JTextField that is in focus into calling its action listeners. It can not use the robot framework, because that will make every program think enter is pressed, which is a problem.

Here is the backstory:

I have a program (written in Swing) which allows someone to enter data in many textfields and other things by hitting enter after typing in the data. It works great.

However, most people that use it are using a second program at the same time which automatically listens for an enter key and shuts off a robot (for those of you who are familiar with FIRST robotics, I'm talking about the SmartDashboard and the Driver Station). There have been quite a few complaints about this. People want to enter data without disabling the robot. As it turns out, the SmartDashboard (the program people want to hit enter on) allows custom swing components to be run along with it.

not entirely sure if I understand your requirement correctly (will delete this if not) ...

You can manually dispatch an event to whatever component you want to address. In the case of wanting to dispatch to the focusOwner

  • find the focusOwner by querying the KeyboardFocusManager
  • create a keyEvent with the focusOwner as sender
  • dispatch that event to the focusOwner

Something like:

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

Edit

added some lines for actually playing with it (@Joe commented it's not working). Clicking the button triggers the action of the focused textField (here simply prints out the field's name) Local context is vista and jdk6u27.

You might try getRootPane().setDefaultButton() on the frame. There's an example here .

Grabbing the element with the focus and manually dispatching an enter event didn't quite work, but because I just wanted to effect various JTextField, I came up with a similar solution:

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

Thanks for pointing me in the right direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM