问题描述
我正在一个项目中,我需要为每个 JRadioButton
添加一个快捷键,同时查看另一个,而我正在使用一些其他自定义 Action
s我决定在每个 JRadioButton上都使用
s,但是它要求我按 setAction
方法 ALT + 1
- ALT + 5
来触发 CustomAction
类的 actionPerformed
方法。
I'm working in a project where I need to add a key shortcut for each JRadioButton
, while looking on another similar question and as I'm using some other custom Action
s I decided to use the method setAction
on each of my JRadioButton
s, however it requires me to press ALT + 1
- ALT + 5
to "trigger" the actionPerformed
method of my CustomAction
class.
如何我可以修改此类以仅按 1
- 5
并获得相同的行为吗?
How can I modify this class in order to just press 1
- 5
and get the same behaviour?
这是我编写的用于演示此问题的代码:
This is the code I made that demonstrates this issue:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class RadioButtonSelectableByNumbers {
private JFrame frame;
private JRadioButton buttons[];
private ButtonGroup group;
public RadioButtonSelectableByNumbers() {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RadioButtonSelectableByNumbers().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("frame");
buttons = new JRadioButton[5];
group = new ButtonGroup();
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JRadioButton();
switch (i) {
case 0:
buttons[i].setAction(new CustomAction(String.valueOf(i + 1), KeyEvent.VK_1));
break;
case 1:
buttons[i].setAction(new CustomAction(String.valueOf(i + 1), KeyEvent.VK_2));
break;
case 2:
buttons[i].setAction(new CustomAction(String.valueOf(i + 1), KeyEvent.VK_3));
break;
case 3:
buttons[i].setAction(new CustomAction(String.valueOf(i + 1), KeyEvent.VK_4));
break;
default:
buttons[i].setAction(new CustomAction(String.valueOf(i + 1), KeyEvent.VK_5));
break;
}
group.add(buttons[i]);
frame.getContentPane().add(buttons[i]);
}
frame.pack();
frame.setVisible(true);
}
class CustomAction extends AbstractAction {
public CustomAction(String name, Integer mnemonic, Integer modifier) {
super(name);
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(mnemonic, modifier));
}
public CustomAction(String name, Integer mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("radio clicked");
}
}
}
推荐答案
如何在Swing中将任何键绑定到组件?按键绑定:。
How do you tie any key to a component in Swing? Key Bindings: Key Bindings Tutorial.
请耐心等待,我在看您的代码...
Hang on while I look at your code...
例如
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class RadioButtonSelectableByNumbers {
private JFrame frame;
private JRadioButton buttons[];
private ButtonGroup group;
public RadioButtonSelectableByNumbers() {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RadioButtonSelectableByNumbers().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame);
buttons = new JRadioButton[5];
group = new ButtonGroup();
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
for (int i = 0; i < buttons.length; i++) {
JRadioButton rbtn = createButton(i);
buttons[i] = rbtn;
frame.getContentPane().add(rbtn);
}
frame.pack();
frame.setVisible(true);
}
private JRadioButton createButton(int i) {
String name = String.valueOf(i + 1);
int stdMnemonic = KeyEvent.VK_1 + i; // for standard number keys
int numpadMnemonic = KeyEvent.VK_NUMPAD1 + i; // for numpad number keys
Action action = new CustomAction(name, stdMnemonic);
JRadioButton rBtn = new JRadioButton(action);
group.add(rBtn);
// bindings active if window is focused. Component doesn't have to be focused
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = rBtn.getInputMap(condition);
ActionMap actionMap = rBtn.getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(stdMnemonic, 0);
KeyStroke keyStroke2 = KeyStroke.getKeyStroke(numpadMnemonic, 0);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), action);
inputMap.put(keyStroke2, keyStroke2.toString());
actionMap.put(keyStroke2.toString(), action);
return rBtn;
}
class CustomAction extends AbstractAction {
public CustomAction(String name, Integer mnemonic, Integer modifier) {
super(name);
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(mnemonic, modifier));
}
public CustomAction(String name, Integer mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("radio clicked: " + e.getActionCommand());
}
}
}
另一种解决方案,可能是更好的是,因为通常JRadioButtons不使用ActionListeners,所以创建一个仅单击按钮的AbstractAction即可。在下面的示例中,MyAction会执行此操作,并为活动的JRadioButton提供焦点:
Another solution, that may be better, since usually JRadioButtons don't use ActionListeners, is to create an AbstractAction that simply clicks the button. In the example below, MyAction does this, as well as gives the active JRadioButton the focus:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class NumberActions extends JPanel {
private ButtonGroup buttonGroup = new ButtonGroup();
public NumberActions() {
ItemListener itemListener = new MyItemListener();
setLayout(new GridLayout(1, 0));
for (int i = 0; i < 10; i++) {
JRadioButton rBtn = createRadioBtn(i);
rBtn.addItemListener(itemListener);
buttonGroup.add(rBtn);
add(rBtn);
}
}
private JRadioButton createRadioBtn(int i) {
String text = String.valueOf(i);
JRadioButton rBtn = new JRadioButton(text);
rBtn.setActionCommand(text);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = rBtn.getInputMap(condition);
ActionMap actionMap = rBtn.getActionMap();
Action action = new MyAction(rBtn);
bindAction(inputMap, actionMap, action, KeyEvent.VK_0 + i);
bindAction(inputMap, actionMap, action, KeyEvent.VK_NUMPAD0 + i);
return rBtn;
}
private void bindAction(InputMap inputMap, ActionMap actionMap, Action action, int mnemonic) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(mnemonic, 0);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), action);
}
private class MyItemListener implements ItemListener {
@Override
public void itemStateChanged(ItemEvent iEvt) {
if (iEvt.getStateChange() == ItemEvent.SELECTED) {
AbstractButton btn = (AbstractButton) iEvt.getSource();
System.out.println("Button: " + btn.getActionCommand());
}
}
}
private class MyAction extends AbstractAction {
private AbstractButton btn;
public MyAction(AbstractButton btn) {
this.btn = btn;
}
@Override
public void actionPerformed(ActionEvent e) {
btn.requestFocusInWindow();
btn.doClick();
}
}
private static void createAndShowGui() {
NumberActions mainPanel = new NumberActions();
JFrame frame = new JFrame("NumberActions");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
编辑:代码固定
这篇关于如何在没有修饰符的情况下为JRadioButton设置快捷键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!