Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I control context menus in other (Windows) applications using Java Robot and Swing buttons
    text
    copied!<p>I have written an extensive on-screen keyboard (OSK) in Java. This is intended for people with disabilities and needs to be able to do <strong>everything</strong> that a standard keyboard can do. One thing I've noticed that doesn't work is <strong>context menus</strong> - in (most) Windows programs. I want my OSK user to be able to click the 'Context Menu' key (normally beside right-Ctrl on standard keyboard) and use the arrow keys to navigate that menu. The context menu appears fine, but when I click back onto my Frame (to press an arrow key), the context menu disappears. </p> <p>Anybody got any ideas as to how this might be achieved (probably a fairly monstrous 'hack' required I would think)? I'm pretty sure the context is disappearing because a mouse-click is occurring elsewhere on the screen (hard to get around that when you need to actually click something!).</p> <p>Below is a test app. I can use it to navigate down through a context menu in NetBeans successfully, but not in any other application I've tried (e.g. Windows Explorer).</p> <pre><code>import java.awt.Robot; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; public class RobotContextMenuTest extends JFrame implements ActionListener { Robot R; JPanel JP; JButton JBmenu, JBdown; public RobotContextMenuTest() { try { R = new Robot(); } catch(Exception e) { e.printStackTrace(); } JP = new JPanel(); getContentPane().add(JP); JBmenu = new JButton("Menu"); JBmenu.addActionListener(this); JP.add(JBmenu); JBdown = new JButton("Down"); JBdown.addActionListener(this); JP.add(JBdown); setFocusableWindowState(false); setAlwaysOnTop(true); setSize(200,80); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String args[]) { new RobotContextMenuTest(); } public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("Menu")) { R.keyPress(KeyEvent.VK_CONTEXT_MENU); R.keyRelease(KeyEvent.VK_CONTEXT_MENU); } else if(e.getActionCommand().equals("Down")) { R.keyPress(KeyEvent.VK_DOWN); R.keyRelease(KeyEvent.VK_DOWN); } } } </code></pre> <p>Finally, here's what I've tried:</p> <ul> <li>Using MouseListener on the buttons instead of ActionListener, then 'consuming' the MouseEvent in the hope that the other application won't register it and hide the context menu.</li> <li>I made a Threaded test application that is able to show any context menu and automatically scan down through it (once every second) but that doesn't really solve my problem! I want the context menu navigation to be controlled by the user's mouse clicks.</li> <li>I've tried using JNativeHook as an alternative method of capturing mouse clicks but the result is the same.</li> </ul> <p>Sorry for the long-winded question but it's a fairly complicated problem! Incidentally, the standard Windows 7 OSK can't do this either but <a href="http://www.wivik.com/" rel="nofollow">WiViK</a> can. Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload