KeyListener
работает (в большинстве случаев) только для компонентов, которые в данный момент сосредоточены. Это также не будет работать, если вы добавите его в контейнер целевого компонента в случае, когда этот компонент потребляет ключевые события. Регистрация действия клавиатуры была бы лучшим способом доступа к горячим клавишам всего окна.
Вот небольшой пример того, как это можно сделать:
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 );
}
} );
}
}
Обратите внимание, что я регистрирую горячую клавишуна JRootPane
из JFrame
здесь, но, как правило, это не имеет значения, потому что условие JComponent.WHEN_IN_FOCUSED_WINDOW
- это означает, что вы можете зарегистрировать его на любом компоненте в окне, и пока окно сосредоточено в системе, вы будетеполучить событие action.
В качестве альтернативы, если в вашем приложении есть JMenuBar
с элементами меню, которые будут выполнять нужные вам действия - вы можете указать ускорители для этих элементов меню, и они будут обрабатывать действие при указанной горячей клавише насвои собственные.
Я также рекомендую прочитать статью из учебника по Swing camickr , предложенную в другом ответе.