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.
¿Has probado usar doClick() ?
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);
}
}
}
}
De: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html
/**
* Click a button on screen
*
* @param button Button to click
* @param millis Time that button will remain "clicked" in milliseconds
*/
public void click(AbstractButton button, int millis) {
b.doClick(millis);
}
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);
}
Siempre puedes simularlo disparando un evento de acción con él como fuente.
http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html
Para activarlo, crea el evento de acción anterior y cualquier oyente que quieras solo llama
ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);