【问题标题】:Programmatically clicking a GUI button in Java Swing以编程方式单击 Java Swing 中的 GUI 按钮
【发布时间】:2016-06-15 15:36:21
【问题描述】:

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

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

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

【问题讨论】:

标签: java swing awtrobot


【解决方案1】:

您是否尝试过使用doClick()

【讨论】:

  • 看起来 doClick() 可以完成这项工作!我以前应该注意到的。我想我错过了它,因为它不是直接在 JButton 中定义的,它是从 AbstractButton 继承的。
  • @Gigatron - 是的。抽象有时会使您很难知道什么是可用的(特别是如果没有好的文档——感谢 JavaDocs 的上帝)。很高兴我能帮上忙!
  • 也许 click()press() 会是更好的名字
  • 同意.. 或类似simulateClick()
【解决方案2】:

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

【讨论】:

  • 这是我之前想到的方法,但我觉得必须有一个更简单的解决方案......确实有doClick()的简单解决方案。
  • 这样你就可以确定,键盘记录器甚至更好:鼠标记录器也会捕捉到这个事件:D
  • Robot 类已经有一个 delay() 方法来执行暂停。
  • 由于 Java 9 InputEvent.BUTTON1_MASK 已被弃用,取而代之的是 InputEvent.BUTTON1_DOWN_MASK
【解决方案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); 直观地按下按钮(两者都由助记符更改),并通过将两者都设置为@987654327 来直观地释放按钮@。当按钮同时被按下和武装时调用model.setPressed(false),按钮会自动触发一个ActionEvent(调用model.setArmed(false)只会在视觉上改变按钮)。

[引用自 ButtonModel Java API 文档] 一个按钮被触发,一个 ActionEvent 被触发,当模型被武装时释放鼠标[...]

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

工作代码:按 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);
      }
    }
  }
}

【讨论】:

    【解决方案4】:

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

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

    要触发它,请创建上面的动作事件,以及您想要调用的任何侦听器

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

    【讨论】:

      【解决方案5】:

      发件人: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);
      }
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2013-10-09
          • 2017-06-17
          • 2013-05-23
          • 1970-01-01
          • 2017-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-26
          相关资源
          最近更新 更多