tutorial texto interfaz grafica español ejemplos cuadro componentes clase java swing awtrobot

texto - jlabel en java



Hacer clic en un botón GUI programáticamente en Java Swing (6)

¿Cómo podría hacer clic en un Swing JButton mediante programación de forma que registrara todos los eventos de acción / mouse relevantes y fuera visible para el usuario (es decir, vería que se presionó el botón como si realmente lo hubieran hecho)?

El botón está en la misma aplicación que estoy ejecutando; No estoy tratando de controlar un botón en otra aplicación. Supongo que podría inyectar directamente eventos en la cola, pero preferiría evitar ese enfoque si fuera posible, y hacerlo de esa manera no mostraría un clic visible.

Veo que la clase java.awt.Robot ofrece métodos para mover el mouse y hacer clic con el mouse, pero no para hacer que haga clic en un botón en particular.



Aunque el button.doClick() estaba satisfecho con button.doClick() , estaba buscando algo así como lo que sucede después de configurar un mnemónico, es decir, con button.setMnemonic(KeyEvent.VK_A) . Puedes mantener presionado ALT + A sin que suceda nada (excepto el cambio visual). Y al soltar la tecla A (con o sin ALT), el botón dispara un ActionEvent.

Descubrí que puedo obtener el ButtonModel (ver Java 8 API ) con button.getModel() , luego visualmente presionar el botón con model.setPressed(true); model.setArmed(true); model.setPressed(true); model.setArmed(true); (ambos son modificados por mnemotécnicos), y suelte visualmente el botón estableciendo ambos en false . Y cuando se model.setPressed(false) mientras el botón está presionado y armado, el botón dispara un ActionEvent automáticamente (llamar a model.setArmed(false) solo cambia el botón visualmente).

[Cita de la documentación de la API Java de ButtonModel] Se activa un botón y se activa un evento ActionEvent cuando se suelta el mouse mientras el modelo está armado [...]

Para que la aplicación reaccione a las pulsaciones de teclas cuando el botón está visible (sin que la ventana que lo contiene o el botón deba ser el propietario del foco, es decir, cuando se enfoca otro componente de la ventana) utilicé enlaces de teclas (consulte el Tutorial oficial de Java ).

Código de trabajo: presione MAYÚS + A para presionar visualmente el botón (al contrario de presionar ALT con la tecla después de que se configuró el mnemónico con button.setMnemonic() ). Y suelte la tecla para imprimir el comando de acción ("botón") en la consola.

// MnemonicCode.java import javax.swing.*; import java.awt.event.*; public class MnemonicCode extends JFrame { public MnemonicCode(int keyCode) { JButton button = new JButton("button"); getContentPane().add(button); addMnemonicToButton(button,keyCode); button.addActionListener(new ActionListener () { public void actionPerformed(ActionEvent e) { System.out.println(e.getActionCommand()); } }); pack(); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) throws Exception { MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A); } void addMnemonicToButton(JButton button,int keyCode) { int shiftMask = InputEvent.SHIFT_DOWN_MASK; // signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false); KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true); // get maps for key bindings InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = button.getActionMap(); // add key bindings for pressing and releasing the button inputMap.put(keyPress,"press"+keyCode); actionMap.put("press"+keyCode, new ButtonPress(button)); inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode); actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button)); ///* // add key binding for releasing SHIFT before A // if you use more than one modifier it gets really messy KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true); inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode); actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button)); //*/ } class ButtonPress extends AbstractAction { private JButton button; private ButtonModel model; ButtonPress(JButton button) { this.button = button; this.model = button.getModel(); } public void actionPerformed(ActionEvent e) { // visually press the button model.setPressed(true); model.setArmed(true); button.requestFocusInWindow(); } } class ButtonRelease extends AbstractAction { private ButtonModel model; ButtonRelease(JButton button) { this.model = button.getModel(); } public void actionPerformed(ActionEvent e) { if (model.isPressed()) { // visually release the button // setPressed(false) also makes the button fire an ActionEvent model.setPressed(false); model.setArmed(false); } } } }



Según la respuesta de @ Courteaux, este método hace clic en la primera celda de una JTable:

private void clickFirstCell() { try { jTable1.changeSelection(0, 0, false, false); Point p = jTable1.getLocationOnScreen(); Rectangle cellRect = jTable1.getCellRect(0, 0, true); Robot r = new Robot(); Point mouse = MouseInfo.getPointerInfo().getLocation(); r.mouseMove(p.x + cellRect.x + cellRect.width / 2, p.y + cellRect.y + cellRect.height / 2); r.mousePress(InputEvent.BUTTON1_MASK); try { Thread.sleep(50); } catch (Exception e) { } r.mouseRelease(InputEvent.BUTTON1_MASK); r.mouseMove(mouse.x, mouse.y); } catch (AWTException ex) { } }


Si doClick() no es lo que desea, puede mover el mouse realmente al botón y presionarlo:

public void click(AbstractButton button, int millis) throws AWTException { Point p = button.getLocationOnScreen(); Robot r = new Robot(); r.mouseMove(p.x + button.getWidth() / 2, p.y + button.getHeight() / 2); r.mousePress(InputEvent.BUTTON1_MASK); try { Thread.sleep(millis); } catch (Exception e) {} r.mouseRelease(InputEvent.BUTTON1_MASK); }