Search code examples
javaswingawtrobotmnemonics

java.awt.Robot : hit mnemonics key not working


I created a simple program to use a awt.robot which supposedly press ALT+F and it should open a menu item. But it's not working. Initially I thought focus issue. Then I add a dummy button to get the focus but still id did not work.

Please see the code

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

class MenuActionListener implements ActionListener {

    public void actionPerformed(ActionEvent actionEvent) {

        System.out.println("Selected: " + actionEvent.getActionCommand());

    }
}

public class MenuAction {

    public static void main(final String args[]) throws AWTException {

        ActionListener menuListener = new MenuActionListener();

        JFrame frame = new JFrame("MenuSample Example");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JMenuBar menuBar = new JMenuBar();

        // File Menu, F - Mnemonic
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        menuBar.add(fileMenu);

        // File->New, N - Mnemonic
        JMenuItem newMenuItem = new JMenuItem("New", KeyEvent.VK_N);
        newMenuItem.addActionListener(menuListener);
        fileMenu.add(newMenuItem);

        frame.setJMenuBar(menuBar);
        frame.setSize(650, 650);

        JButton button = new JButton("Test");
        frame.getContentPane().add("South", button);
        frame.setBounds(100, 100, 400, 400);
        frame.setVisible(true);

        button.requestFocusInWindow();

        Robot robot = new Robot();

        robot.setAutoDelay(500);

        robot.waitForIdle();

        robot.keyPress(KeyEvent.ALT_MASK);

        robot.keyPress(KeyEvent.VK_F);
        robot.keyRelease(KeyEvent.VK_F);
        robot.keyRelease(KeyEvent.ALT_MASK);
        robot.waitForIdle();
    }
}

Solution

  • Two things, first, you should be using KeyEvent.VK_ALT and not KeyEvent.ALT_MASK and second, the window may not be visible/active when you Robot code executes, you need to wait until the window has been made visible and even then, you may need to execute the task at some time in the future to ensure that the OS has made the window visible, for example...

    import java.awt.AWTException;
    import java.awt.Robot;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.InputEvent;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.SwingUtilities;
    
    public class MenuAction {
    
        public static void main(final String args[]) throws AWTException {
    
            ActionListener menuListener = new MenuActionListener();
    
            JFrame frame = new JFrame("MenuSample Example");
    
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            JMenuBar menuBar = new JMenuBar();
    
            // File Menu, F - Mnemonic
            JMenu fileMenu = new JMenu("File");
            fileMenu.setMnemonic(KeyEvent.VK_F);
            menuBar.add(fileMenu);
    
            // File->New, N - Mnemonic
            JMenuItem newMenuItem = new JMenuItem("New", KeyEvent.VK_N);
            newMenuItem.addActionListener(menuListener);
            fileMenu.add(newMenuItem);
    
            frame.setJMenuBar(menuBar);
            frame.setSize(650, 650);
    
            JButton button = new JButton("Test");
            frame.getContentPane().add("South", button);
            frame.setBounds(100, 100, 400, 400);
            frame.addWindowListener(new WindowAdapter() {
    
                @Override
                public void windowOpened(WindowEvent e) {
                    button.requestFocusInWindow();
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
    
                            try {
                                Robot robot = new Robot();
    
                                robot.setAutoDelay(500);
    
                                robot.waitForIdle();
    
                                robot.keyPress(KeyEvent.VK_ALT);
    
                                robot.keyPress(KeyEvent.VK_F);
                                robot.keyRelease(KeyEvent.VK_F);
                                robot.keyRelease(KeyEvent.VK_ALT);
                                robot.waitForIdle();
                            } catch (AWTException exp) {
                                exp.printStackTrace();
                            }
                        }
                    }).start();
                }
            });
            frame.setVisible(true);
        }
    
        public static class MenuActionListener implements ActionListener {
    
            public void actionPerformed(ActionEvent actionEvent) {
    
                System.out.println("Selected: " + actionEvent.getActionCommand());
    
            }
        }
    }