以编程方式单击Java Swing中的GUI按钮

时间:2011-02-24 19:09:03

标签: java swing awtrobot

我如何以编程方式单击Swing JButton,以便注册所有相关的动作/鼠标事件并且对用户可见(即他们看到按钮被按下就像他们实际点击它一样)?

按钮与我正在运行的应用程序相同;我不是想控制另一个应用程序中的按钮。我想我可以直接将事件注入队列,但是如果可能的话我宁愿避免使用这种方法,这样做也不会显示可见的点击。

我看到java.awt.Robot类提供了移动鼠标并单击鼠标的方法,但没有让它单击特定按钮。

6 个答案:

答案 0 :(得分:94)

您是否尝试过使用doClick()

答案 1 :(得分:9)

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

答案 2 :(得分:3)

即使提问者对button.doClick()感到满意,我也在寻找类似于设置助记符之后发生的事情,即使用button.setMnemonic(KeyEvent.VK_A)。实际上你可以按住ALT + A而不会发生任何事情(视觉变化除外)。在释放键A(有或没有ALT)时,按钮会触发一个ActionEvent。

我发现我可以使用button.getModel()获取ButtonModel(请参阅Java 8 API),然后用model.setPressed(true); model.setArmed(true);直观地按下按钮(两者都由助记符更改),并在视觉上释放按钮将两者都设置为false。当按下并按下按钮时调用model.setPressed(false)时,该按钮会自动触发一个ActionEvent(调用model.setArmed(false)只会在视觉上改变按钮)。

  

[来自ButtonModel Java API文档的引用]   触发一个按钮,当模型布防时释放鼠标时会触发一个ActionEvent [...]

当按钮可见时,使应用程序对按键做出反应(没有包含窗口或按钮需要成为焦点所有者,即当窗口中的另一个组件被聚焦时)我使用了键绑定(参见{{ 3}})。

工作代码:按SHIFT + A直观地按下按钮(与使用button.setMnemonic()设置助记符后用键按ALT相反)。并释放键以在控制台上打印动作命令(“按钮”)。

// 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 :(得分:2)

你总是可以通过用它作为源来触发动作事件来模拟它。

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

要触发它,创建上面的动作事件,以及你想要的任何监听器,只需调用

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

答案 4 :(得分:1)

来自: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);
}

答案 5 :(得分:0)

根据@ 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) {
    }
}