Программное нажатие кнопки GUI в Java Swing - PullRequest
51 голосов
/ 24 февраля 2011

Как бы я программно щелкнул по кнопке Swing JButton таким образом, чтобы регистрировать все соответствующие события действия / мыши и быть видимым для пользователя (т. Е. Они будут видеть нажатие кнопки, как будто они действительно нажимают на нее)?*

Кнопка находится в том же приложении, которое я запускаю;Я не пытаюсь контролировать кнопку в другом приложении.Я полагаю, что мог бы напрямую вводить события в очередь, но я бы предпочел избегать такого подхода, если это возможно, и при таком способе не было бы видно видимый щелчок.Класс предлагает методы для перемещения мыши и щелчка мышью, но не для того, чтобы заставить ее щелкать по определенной кнопке.

Ответы [ 6 ]

94 голосов
/ 24 февраля 2011

Вы пытались использовать doClick () ?

9 голосов
/ 24 февраля 2011

Если doClick() не то, что вам нужно, вы можете переместить мышь на кнопку и нажать ее:

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);
}
3 голосов
/ 23 мая 2014

Несмотря на то, что спрашивающий был удовлетворен button.doClick(), я искал что-то вроде того, что происходит после установки мнемоники, то есть с button.setMnemonic(KeyEvent.VK_A).Вы можете фактически удерживать ALT + A без чего-либо происходящего (кроме визуального изменения).И после отпускания ключа A (с или без ALT) кнопка запускает ActionEvent.

Я обнаружил, что могу получить ButtonModel (см. Java 8 API ) с button.getModel(), затем визуально нажмите кнопку с помощью model.setPressed(true); model.setArmed(true); (оба мнемоники меняются) и визуально отпустите кнопку, установив для обоих параметров значение false.И когда model.setPressed(false) вызывается, когда кнопка и нажата, и включена, кнопка автоматически запускает ActionEvent (вызов model.setArmed(false) только изменяет кнопку визуально).

[Цитата из документации ButtonModel по Java API] Кнопка срабатывает, и ActionEvent запускается, когда мышь отпускается, когда модель активирована [...]

Чтобы приложение реагировало на нажатия клавиш, когда кнопка видна (без содержащего окна или кнопки, которая должна быть владельцем фокуса, т. е. когда фокусируется другой компонент в окне) Я использовал привязки клавиш (см. Официальное руководство по Java ).

Рабочий код: Нажмите SHIFT + A, чтобы визуально нажать кнопку (в отличие от нажатия ALT клавишей после того, как мнемоника установлена ​​с помощью button.setMnemonic()).И отпустите клавишу, чтобы напечатать команду действия («кнопка») на консоли.

// 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);
      }
    }
  }
}
2 голосов
/ 24 февраля 2011

Вы всегда можете смоделировать его, запустив событие действия с источником.

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

Чтобы запустить его, создайте событие action выше, и любого слушателя, которого вы хотите, просто вызовите

ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);
1 голос
/ 24 февраля 2011

От: 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);
}
0 голосов
/ 15 июня 2016

На основе ответа @ Courteaux, этот метод щелкает первую ячейку в 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) {
    }
}
...