且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在具有许多JTextField的Java Swing JFrame实例中获取键事件?

更新时间:2023-12-05 10:14:22

KeyListener仅在大多数情况下适用于当前关注的组件.如果将其添加到焦点组件的容器中,以防该组件消耗键事件,它也将无法工作.注册键盘操作将是处理窗口范围的热键的更好方法.

KeyListener only works (in most cases) for components that are currently focused. It also won't work if you add it to a container of the focused component in case when that component consumes key events. Registering a keyboard action would be a better way to approach window-wide hotkeys.

这是一个如何完成的小例子:

Here is a small example of how it could be done:

public class FrameHotkey
{
    public static void main ( final String[] args )
    {
        SwingUtilities.invokeLater ( new Runnable ()
        {
            @Override
            public void run ()
            {
                final JFrame frame = new JFrame ();

                frame.setLayout ( new FlowLayout ( FlowLayout.CENTER, 15, 15 ) );
                frame.add ( new JLabel ( "Field 1:" ) );
                frame.add ( new JTextField ( "Field 1", 15 ) );
                frame.add ( new JLabel ( "Field 2:" ) );
                frame.add ( new JTextField ( "Field 2", 15 ) );

                // Hotkey for the F1 in window
                frame.getRootPane ().registerKeyboardAction ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        JOptionPane.showMessageDialog ( frame, "F1 have been pressed!" );
                    }
                }, KeyStroke.getKeyStroke ( KeyEvent.VK_F1, 0 ), JComponent.WHEN_IN_FOCUSED_WINDOW );

                frame.setDefaultCloseOperation ( WindowConstants.EXIT_ON_CLOSE );
                frame.pack ();
                frame.setLocationRelativeTo ( null );
                frame.setVisible ( true );
            }
        } );
    }
}

请注意,我在这里在JFrameJRootPane上注册热键,但这通常没关系,因为条件是JComponent.WHEN_IN_FOCUSED_WINDOW-这意味着您可以在窗口中的任何组件上注册它,只要当窗口聚焦在系统中时,您将收到操作事件.

Note that I'm registering hotkey on JRootPane of the JFrame here, but it generally does't matter because condition is JComponent.WHEN_IN_FOCUSED_WINDOW - meaning that you can register it on any component in the window and as long as the window is focused in the system you will receive the action event.

或者,如果您的应用程序具有JMenuBar,其中的菜单项可以执行所需的操作-您可以为这些菜单项指定加速器,它们将根据指定的热键自行处理操作.

Alternatively, if your application has a JMenuBar with menu items that would perform the actions you desire - you can specify accelerators for those menu items and they will handle the action upon specified hotkey on their own.

我还建议您阅读其他答案中提供的Swing教程 camickr 中的文章.

I also recommend reading the article from Swing tutorial camickr offered in the other answer.