Keystroke/Hot Key for JButton in Java

我是研究僧i 提交于 2021-02-10 07:14:25

问题


Initially I was using JMenu and establishing hot keys to work using accelerator. It was working perfectly. Now I want the same behavior in JButton but I am stuck. Here is the code that I wrote : Please share your ideas so I can go in the right path.

import javax.swing.*;

import java.awt.Event;
import java.awt.event.*;
import java.util.Arrays;

public class ShowDialogBox{
    JFrame frame;
    public static void main(String[] args){
        ShowDialogBox db = new ShowDialogBox();
    }

    public ShowDialogBox(){
        frame = new JFrame("Show Message Dialog");
        // create an Action doing what you want
        KeyStroke keySave = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK); 
        Action performSave = new AbstractAction("Click Me") {  
            public void actionPerformed(ActionEvent e) {     
                 //do your save
                 System.out.println("clickMe");
            }
        }; 


        JButton button = new JButton("Click Me");


        button.getActionMap().put("Click Me", performSave);
        button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keySave, "Click Me");

        button.addActionListener(new MyAction());
        frame.add(button);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public class MyAction implements ActionListener{
        public void actionPerformed(ActionEvent e){



            String[] items = {
                    "1", "2", "3"
                };
                JList list = new JList(items);
                JPanel panel = new JPanel();
                panel.add(list);
                JOptionPane.showMessageDialog(null, panel);

        }

Thanks in advance


回答1:


To get your key bindings to work, use a KeyEvent.CTRL_DOWN_MASK not the KeyEvent.CTRL_MASK.

Myself, I prefer to use AbstractActions over ActionListeners, since this way menus and buttons can share the same Actions, and the Actions can have their own mnemonic key, although this needs to be an alt-key combination. For example:

import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class ShowMyDialogTest {

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Show MyDialog Test");

      JPanel mainPanel = new JPanel();
      Action showAction = new ShowDialogAction(frame, "Show Dialog");
      final JButton showDialogBtn = new JButton(showAction);
      mainPanel.add(showDialogBtn);
      mainPanel.setPreferredSize(new Dimension(600, 400));

      KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK);
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = showDialogBtn.getInputMap(condition);
      ActionMap actionMap = showDialogBtn.getActionMap();
      inputMap.put(keyStroke, keyStroke.toString());
      actionMap.put(keyStroke.toString(), new AbstractAction() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            showDialogBtn.doClick();
         }
      });

      JMenuItem showMenuItem = new JMenuItem(showAction);
      JMenuItem exitMenuItem = new JMenuItem(new DisposeAction("Exit", KeyEvent.VK_X));
      JMenu fileMenu = new JMenu("File"); 
      fileMenu.setMnemonic(KeyEvent.VK_F);
      fileMenu.add(showMenuItem);
      fileMenu.add(exitMenuItem);

      JMenuBar menuBar = new JMenuBar();
      menuBar.add(fileMenu);
      frame.setJMenuBar(menuBar);      

      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(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ShowDialogAction extends AbstractAction {
   private JFrame frame;
   private ShowDialogPanel dialogPanel;
   private JDialog dialog;

   public ShowDialogAction(JFrame frame, String name) {
      super(name);
      int mnemonic = (int) name.charAt(0);
      putValue(MNEMONIC_KEY, mnemonic);
      this.frame = frame;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      if (dialogPanel == null) {
         dialogPanel = new ShowDialogPanel();
      }
      if (dialog == null) {
         dialog = new JDialog(frame, "My Dialog", ModalityType.APPLICATION_MODAL);
         dialog.getContentPane().add(dialogPanel);
         dialog.pack();
      }
      dialog.setLocationRelativeTo(frame);
      dialog.setVisible(true);
      // TODO add any code that extracts data from dialogPanel

   }
}

class ShowDialogPanel extends JPanel {
   private JButton button = new JButton(new DisposeAction("Close", KeyEvent.VK_C));

   public ShowDialogPanel() {
      add(button);
   }
}

class DisposeAction extends AbstractAction {
   private static final long serialVersionUID = 1L;

   public DisposeAction(String name, int mnemonic) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      Component component = (Component) e.getSource();
      Window win = SwingUtilities.getWindowAncestor(component);
      if (win == null) {
         JPopupMenu popup = (JPopupMenu) component.getParent();
         if (popup == null) {
            return;
         }
         component = popup.getInvoker();
         win = SwingUtilities.getWindowAncestor(component);
      }
      win.dispose();
   }
}


来源:https://stackoverflow.com/questions/30925438/keystroke-hot-key-for-jbutton-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!