简体   繁体   English

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

[英]Programmatically clicking a GUI button in Java Swing

How would I programmatically click a Swing JButton in a way that would register all the relevant action/mouse events and be visible to the user (ie they'd see the button being pressed as if they actually clicked it)?我如何以编程方式单击 Swing JButton 以注册所有相关的动作/鼠标事件并对用户可见(即他们会看到按钮被按下,就像他们实际单击它一样)?

The button is in the same application I'm running;该按钮位于我正在运行的同一个应用程序中; I'm not trying to control a button in another application.我不想控制另一个应用程序中的按钮。 I suppose I could directly inject events into the queue, but I'd prefer to avoid that approach if possible, and doing it that way wouldn't show a visible click.我想我可以直接将事件注入队列,但如果可能的话,我宁愿避免这种方法,这样做不会显示可见的点击。

I see the java.awt.Robot class offers methods to move the mouse and click the mouse, but not to make it click a particular button.我看到 java.awt.Robot 类提供了移动鼠标和单击鼠标的方法,但不能让它单击特定按钮。

您是否尝试过使用doClick()

If doClick() is not what you want, you can move the mouse really to the button and press it:如果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);
}

Even though the asker was satisfied with button.doClick() , I was looking for something like what happens after setting a mnemonic, ie with button.setMnemonic(KeyEvent.VK_A) .即使提问者对button.doClick()感到满意,我也在寻找类似设置助记符后发生的事情,即使用button.setMnemonic(KeyEvent.VK_A) You can actually hold down ALT + A without anything happening (except the visual change).您实际上可以按住 ALT + A 而不会发生任何事情(视觉变化除外)。 And upon release of the key A (with or without ALT), the button fires an ActionEvent.并且在释放键 A(带或不带 ALT)时,按钮会触发一个 ActionEvent。

I found that I can get the ButtonModel (see Java 8 API ) with button.getModel() , then visually press the button with model.setPressed(true); model.setArmed(true);我发现我可以使用 button.getModel() 获取 ButtonModel(参见Java 8 API button.getModel() ,然后使用model.setPressed(true); model.setArmed(true); model.setPressed(true); model.setArmed(true); (both are changed by mnemonics), and visually release the button by setting both to false . (两者都由助记符更改),并通过将两者都设置为false来直观地释放按钮。 And when model.setPressed(false) is called while the button is both pressed and armed, the button fires an ActionEvent automatically (calling model.setArmed(false) only changes the button visually).当按钮同时被按下和武装时调用 model.setPressed(false model.setPressed(false)时,按钮会自动触发 ActionEvent(调用model.setArmed(false)只会在视觉上改变按钮)。

[Quote from ButtonModel Java API documentation] A button is triggered, and an ActionEvent is fired, when the mouse is released while the model is armed [...] [来自 ButtonModel Java API 文档的引述] 当在模型武装时释放鼠标时,会触发一个按钮并触发一个 ActionEvent [...]

To make the application react to key presses when the button is visible (without the containing window or the button needing to be the focus owner, ie when another component in the window is focussed) I used key bindings (see the Official Java Tutorial ).为了让应用程序在按钮可见时对按键做出反应(没有包含窗口或按钮需要成为焦点所有者,即当窗口中的另一个组件被聚焦时),我使用了键绑定(参见官方 Java 教程)。

Working code: Press SHIFT + A to visually press the button (in contrast to pressing ALT with the key after the mnemonic is set with button.setMnemonic() ).工作代码:按 SHIFT + A 以直观地按下按钮(与在使用button.setMnemonic()设置助记符后按 ALT 键相反)。 And release the key to print the action command ("button") on the 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(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);
      }
    }
  }
}

You could always simulate it by firing an action event with it as the source.您总是可以通过触发一个以它为源的动作事件来模拟它。

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

To fire it, create the action event above, and whatever listener you want just call要触发它,请创建上面的动作事件,以及您想要调用的任何侦听器

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

From: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html来自: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);
}

Based on @Courteaux's answer, this method clicks the first cell in a JTable:根据@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) {
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM