Вам необходимо:
Обновите InputMap
компонента, добавив новый KeyStroke
, чтобы он указывал на существующий Action
.
Не позволяет существующему KeyStroke
в InputMap
вызывать существующее Action
. Этот шаг не является обязательным, если вы хотите использовать обе комбинации клавиш для вызова действия по умолчанию.
Примечание:
- вам нужно обновить
InputMap
для «нажатых» и «отпущенных» клавиш
- Обновления
InputMap
должны выполняться в указанном выше порядке.
Модифицируя код из примера Hovercrafts, вы можете сделать:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class AlterSpaceBinding extends JPanel {
private JButton myButton = new JButton("My Button -- associate with \"B\" key");
public AlterSpaceBinding() {
myButton = alterDefaultButtonAction(myButton, KeyEvent.VK_B);
myButton.addActionListener(l -> {
System.out.println("button pressed");
});
add(myButton);
add(new JButton("Second Button -- no change"));
}
public static JButton alterDefaultButtonAction(JButton button, int desiredKeyCode) {
// get the correct InputMap
InputMap inputMap = button.getInputMap(JComponent.WHEN_FOCUSED);
// get both key strokes for space key, but pressed and released
KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);
// key stroke for desired key code
KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);
// share the Action with desired KeyStroke
inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));
// disable original KeyStrokes (optional)
inputMap.put(spaceKeyPressed, "none");
inputMap.put(spaceKeyReleased, "none");
return button;
}
private static void createAndShowGui() {
AlterSpaceBinding mainPanel = new AlterSpaceBinding();
JFrame frame = new JFrame("AlterSpaceBinding");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Приведенному выше коду не нужно:
- создать пустышку
Action
.
- манипулировать
ActionMap
.
Проверьте Использование привязок клавиш для получения дополнительных примеров манипулирования InputMap
и ActionMap
компонента.
Примечание:
Более вероятный сценарий - вы хотите обновить привязки для всех кнопок в приложении, чтобы у вас был общий LAF. В этом случае вы можете обновить «focusInputMap» из UIManager, который используется всеми JButton:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
SSCCE()
{
add( new JButton("Button 1" ) );
add( new JButton("Button 2" ) );
add( new JButton("Button 3" ) );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
// Update shared InputMap
InputMap inputMap = (InputMap)UIManager.get("Button.focusInputMap");
int desiredKeyCode = KeyEvent.VK_B; // type "b" to invoke Action on button
KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);
// key stroke for desired key code
KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);
// share the Action with desired KeyStroke
inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));
// optionally disable original KeyStrokes
inputMap.put(spaceKeyPressed, "none");
inputMap.put(spaceKeyReleased, "none");
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}