webentwicklung-frage-antwort-db.com.de

Programmgesteuertes Klicken auf eine GUI-Schaltfläche in Java Swing

Wie würde ich programmgesteuert auf eine Swing-JButton-Schaltfläche klicken, um alle relevanten Action-/Mausereignisse zu registrieren und für den Benutzer sichtbar zu sein (d. H. Sie sehen, dass die Schaltfläche gedrückt wird, als würden sie tatsächlich darauf klicken)?

Die Schaltfläche befindet sich in derselben Anwendung, die ich ausführte. Ich versuche nicht, eine Schaltfläche in einer anderen Anwendung zu steuern. Ich vermute, ich könnte Ereignisse direkt in die Warteschlange einschleusen, aber ich würde es vorziehen, wenn möglich, den Ansatz zu meiden, und dies würde keinen sichtbaren Klick zeigen.

Ich sehe die Java.awt.Robot-Klasse bietet Methoden zum Bewegen der Maus und zum Klicken mit der Maus, nicht jedoch zum Klicken auf eine bestimmte Schaltfläche.

50
Gigatron

Haben Sie versucht, doClick () zu verwenden?

90
JasCav

Wenn doClick() nicht das ist, was Sie wollen, können Sie die Maus wirklich auf die Schaltfläche bewegen und drücken:

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

Obwohl der Fragesteller mit button.doClick() zufrieden war, suchte ich nach etwas, was nach dem Einstellen einer Mnemonic passiert, d. H. Mit button.setMnemonic(KeyEvent.VK_A). Sie können ALT + A tatsächlich gedrückt halten, ohne dass etwas passiert (außer der visuellen Änderung). Bei Loslassen der Taste A (mit oder ohne ALT) wird mit der Taste ein ActionEvent ausgelöst.

Ich habe herausgefunden, dass ich das ButtonModel (siehe Java 8 API ) mit button.getModel() erhalten kann, dann visuell die Taste mit model.setPressed(true); model.setArmed(true); (beide werden von Mnemonics geändert) und die Taste visuell freigeben, indem beide auf false gesetzt werden. Wenn model.setPressed(false) aufgerufen wird, während die Schaltfläche sowohl gedrückt als auch aktiviert ist, löst die Schaltfläche automatisch ein ActionEvent aus (der Aufruf von model.setArmed(false) ändert nur die Schaltfläche).

[Zitat aus der ButtonModel Java API-Dokumentation] Eine Schaltfläche wird ausgelöst, und ein ActionEvent wird ausgelöst, wenn die Maus losgelassen wird, während das Modell [...] aktiviert ist.

Damit die Anwendung auf Tastendrücke reagieren kann, wenn die Schaltfläche sichtbar ist (ohne dass das übergeordnete Fenster oder die Schaltfläche der Fokusbesitzer sein muss, dh wenn eine andere Komponente im Fenster fokussiert ist), habe ich Tastenzuordnungen verwendet (siehe Offizielles Java-Tutorial ).

Arbeitscode: Drücken Sie SHIFT + A, um die Taste visuell zu drücken (im Gegensatz zum Drücken von ALT mit der Taste, nachdem die Mnemonic mit button.setMnemonic() eingestellt wurde). Lassen Sie die Taste los, um den Aktionsbefehl ("Button") auf der Konsole zu drucken.

// 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);
      }
    }
  }
}
3
mkdrive2

Sie können es immer simulieren, indem Sie ein Aktionsereignis mit der Quelle als Quelle starten.

http://download.Oracle.com/javase/6/docs/api/Java/awt/event/ActionEvent.html

Um es abzufeuern, erstellen Sie das Aktionsereignis oben und den gewünschten Listener, den Sie einfach anrufen möchten

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

Von: 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);
}
1
Michael K

Basierend auf der Antwort von @ Courteaux klickt diese Methode die erste Zelle in einer JTable an:

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) {
    }
}
0
user586399