Simulating an input key in Swing (without using Robot)

So, I'm trying to write a JButton that will act as an enter key when pressed. He should be able to trick JTextField, which is in focus, to call his listeners to the action. He cannot use the infrastructure of the robot, because it will make every program think that the input is pressed, which is a problem.

Here is the background:

I have a program (written in Swing) that allows someone to enter data in many text fields and other things by pressing the enter button after entering the data. It works great.

However, most people who use it use the second program at the same time, which automatically listens for the input key and turns off the robot (for those of you who are familiar with FIRST robotics, Iโ€™m talking about SmartDashboard and Driver's Station). There were many complaints about this. People want to enter data without shutting down the robot. As it turned out, SmartDashboard (the program people want to get in with is included) allows you to run custom swing components with it.

+4
source share
3 answers

not quite sure if I understood your requirement correctly (will delete it if not) ...

You can manually send an event to any component that you want to address. If necessary, send to focusOwner

  • find focusOwner by querying KeyboardFocusManager
  • create keyEvent with focusOwner as sender
  • send this event to focusOwner

Sort of:

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 a few lines for actual playback with it (@Joe commented that it does not work). Clicking the button causes the action of the focused textField (it simply prints the field name here). The local context is vista and jdk6u27.

+4
source

You can try getRootPane().setDefaultButton() in the frame. Here is an example here .

+2
source

Capturing an element with focus and manually sending an input event did not work, but since I just wanted to use different 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.

+2
source

Source: https://habr.com/ru/post/1401496/


All Articles