【问题标题】:How to set a shortcut key for JRadioButton without modifiers如何在没有修饰符的情况下为 JRadioButton 设置快捷键
【发布时间】:2017-04-18 01:32:24
【问题描述】:

我正在一个项目中工作,我需要为每个 JRadioButton 添加一个快捷键,同时查看另一个 similar question 并且我正在使用其他一些自定义 Actions 我决定使用该方法setAction 在我的每个JRadioButtons 上,但是它需要我按ALT + 1 - ALT + 5 来“触发”我的actionPerformed 类的actionPerformed 方法。

我如何修改这个类以便只按1 - 5 并获得相同的行为?

这是我为演示此问题所做的代码:

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");
        }
    }
}

【问题讨论】:

    标签: java swing actionlistener jradiobutton


    【解决方案1】:

    如何在 Swing 中将任何键绑定到组件?键绑定:Key Bindings Tutorial

    等我看你的代码...

    例如

    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());
            }
        }
    }
    

    另一个可能更好的解决方案是创建一个简单地单击按钮的 AbstractAction,因为 JRadioButtons 通常不使用 ActionListeners。在下面的示例中,MyAction 执行此操作,并为活动的 JRadioButton 提供焦点:

    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());
        }
    }
    

    编辑:代码已修复

    【讨论】:

    • 我现在对键绑定有了更好的理解,当我阅读教程(在你建议之前)时,我有点困惑,现在变得更清楚了。我认为这就是我所缺少的,但是您能解释一下为什么要在这些行中添加i 吗? KeyEvent.VK_1 + i; 和小键盘行?
    • 助记符单调递增。而不是不必要的丑陋和脆弱的 switch/case 语句,让数字在那里计算自己的助记符值。我需要考虑使用不同助记符的标准键和数字键盘键。
    • 哦,是枚举值在增加,我也在找这个,谢谢,等我回到我的电脑上试试,我会接受的
    • @Frakcool:这里不涉及枚举,只是 int 常量。请参阅编辑以回答我认为更好的解决方案,如果您将 JRadioButtons 与 ItemListeners 连接或不连接,则该解决方案将起作用。
    • (1+),我总是忘记用小键盘处理数字的输入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2023-02-11
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多