En cliquant sur un bouton de l’interface graphique dans Java Swing

Comment puis-je cliquer sur un JButton Swing par programmation d’une manière qui enregistrerait tous les événements d’action / souris pertinents et serait visible pour l’utilisateur (c.-à-d. Si le bouton était appuyé comme s’il l’avait cliqué)?

Le bouton est dans la même application que je suis en cours d’exécution; Je n’essaie pas de contrôler un bouton dans une autre application. Je suppose que je pourrais directement injecter des événements dans la queue, mais je préférerais éviter cette approche si possible, et cela ne montrerait pas un clic visible.

Je vois la classe java.awt.Robot propose des méthodes pour déplacer la souris et cliquer avec la souris, mais pas pour la faire cliquer sur un bouton particulier.

Avez-vous essayé d’utiliser doClick () ?

Si doClick() n’est pas ce que vous voulez, vous pouvez déplacer la souris sur le bouton et appuyer dessus:

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

Même si le demandeur était satisfait de button.doClick() , je cherchais quelque chose comme ce qui se passe après avoir défini un mnémonique, c’est-à-dire avec button.setMnemonic(KeyEvent.VK_A) . Vous pouvez réellement maintenir ALT + A sans que rien ne se passe (sauf le changement visuel). Et à la libération de la clé A (avec ou sans ALT), le bouton déclenche un ActionEvent.

J’ai trouvé que je pouvais obtenir ButtonModel (voir l’API Java 8 ) avec button.getModel() , puis appuyer visuellement sur le bouton avec model.setPressed(true); model.setArmed(true); model.setPressed(true); model.setArmed(true); (les deux sont modifiés par des mnémoniques), et relâchez visuellement le bouton en définissant les deux sur false . Et lorsque model.setPressed(false) est appelé alors que le bouton est enfoncé et armé, le bouton déclenche automatiquement un ActionEvent (l’appel de model.setArmed(false) modifie uniquement le bouton visuellement).

[Citation de la documentation de l’API Java de ButtonModel] Un bouton est déclenché et un ActionEvent est déclenché lorsque la souris est relâchée alors que le modèle est armé […]

Pour que l’application réagisse aux touches lorsque le bouton est visible (sans la fenêtre contenant ou le bouton devant être le propriétaire du focus, c’est-à-dire lorsqu’un autre composant de la fenêtre est focalisé), j’ai utilisé des raccourcis clavier (voir le tutoriel officiel Java ).

Code de travail: Appuyez sur SHIFT + A pour appuyer visuellement sur le bouton (au lieu d’appuyer sur ALT avec la touche après que le mnémonique est défini avec button.setMnemonic() ). Et relâchez la touche pour imprimer la commande d’action (“bouton”) sur la console.

 // 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(Ssortingng[] 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); } } } } 

Vous pouvez toujours le simuler en lançant un événement d’action avec lui comme source.

http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html

Pour le lancer, créez l’événement d’action ci-dessus, et quel que soit l’auditeur que vous voulez appeler

 ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform"); myListener.actionPerformed(e); 

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

Sur la base de la réponse de @ Courteaux, cette méthode clique sur la première cellule d’une 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(px + cellRect.x + cellRect.width / 2, py + 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) { } }