javaswingkey-bindingsswingxkeystrokes

Java How to intercept key combinations anywhere on a window using keybindings


My application will be used on a small twin engine aircraft. The environment is "bumpy" and the nipple "mouse" is very hard to use (even in the hanger!). I need to be able to intercept key combinations for at least all the commonly used actions the user wants to take. These would include, for example, alt-C to perform a a calibration, alt-R to start recording data, alt-X to have the app shut down gracefully, etc.

I've only used key Bindings in a demo class and do not understand how use them over an entire window. I have put 5 JPanels containing otherJPpanels and components on my JFrame's ContentPane. All the examples I have found assume some component has focus but pushing TAB 23 times to get to a component is unreasonable.

The app will run under LINUX, probably Ubuntu.


Solution

  • In swing you should add a KeyStroke to the main panel's action map: For instance the following code let you refresh the JFrame that contains the JPanel, each time you press [F10] key:

    public class MainWindow extends JFrame{
        JPanel central;
    
        public MainWindow(){
            central = new JPanel();
            // I assume you define your other 5 panels here
            // and add them to the central JPanel.
            getContentPane().add(central, BorderLayout.CENTER);
            registerRefreshAction();
        }
    
        private void registerRefreshAction(){
            javax.swing.Action refresh = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    JFrame frame = (JFrame) getTopLevelAncestor();
                    frame.setVisible(false);
                    frame.getContentPane().repaint();
                    frame.setVisible(true);
                }
            };
            KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0);
            central.getActionMap().put("Refresh", refresh);
            central.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "Refresh");
        }
    }
    

    You should call registerRefreshAction in some place in your constructor, as shown before. The other components you mention are included inside the 5 panels and don't need to be shown. It is working in Linux.