JButton KeyBinding和setActionCommand

时间:2014-09-18 21:57:20

标签: java swing key key-bindings

我对Swing很新,并且无法理解KeyBinding概念。 我正在尝试向JButton添加JPanel,然后设置其动作命令和KeyBinding。这是我的代码:

JButton b = new JButton("1");
MyAction myaction = new MyAction("1");
b.setAction(myaction);
b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
b.getActionMap().put("one", myaction);
b.setActionCommand("one");

MyAction这里是一个内部类

class MyAction extends AbstractAction {
    public MyAction(String text) {
        super(text);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Action command is: " + e.getActionCommand());
    }
}

现在如果我按下按钮,我会得到这个输出:

Action command is: one

但是,如果我按下键盘上的“1”,我就明白了:

Action command is: 1

为什么会这样?无论按钮按下还是按键绑定触发操作,我该怎么做才能获得相同的动作命令?

2 个答案:

答案 0 :(得分:2)

考虑在AbstractAction本身中设置Action命令键:

class MyAction extends AbstractAction {
    public MyAction(String text) {
        super(text);
        putValue(ACTION_COMMAND_KEY, "one"),
    }
    //...

例如:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class Foo2 extends JPanel {
   private static final String[] NUMBER_TEXTS = {
      "one", "two", "three", "four", "five"
   };


   public Foo2() {

      for (int i = 0; i < NUMBER_TEXTS.length; i++) {
         String numberString = String.valueOf(i + 1);
         Action numberBtnAction = new NumberBtnAction(numberString, NUMBER_TEXTS[i]);
         JButton btn = new JButton(numberBtnAction);
         InputMap inMap = btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
         ActionMap actionMap = btn.getActionMap();

         KeyStroke keyStroke = KeyStroke.getKeyStroke(numberString.charAt(0));
         inMap.put(keyStroke, NUMBER_TEXTS[i]);
         actionMap.put(NUMBER_TEXTS[i], numberBtnAction);

         add(btn);
      }

   }

   private class NumberBtnAction extends AbstractAction {
      public NumberBtnAction(String numberString, String numberText) {
         super(numberString);
         putValue(ACTION_COMMAND_KEY, numberText);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         System.out.println(e.getActionCommand());
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Foo2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Foo2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

修改
或者,您可以使用单独的键绑定操作,只需按下按钮:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class Foo2 extends JPanel {
   private static final String[] NUMBER_TEXTS = {
      "one", "two", "three", "four", "five"
   };


   public Foo2() {

      for (int i = 0; i < NUMBER_TEXTS.length; i++) {
         String numberString = String.valueOf(i + 1);
         Action numberBtnAction = new NumberBtnAction(numberString, NUMBER_TEXTS[i]);
         JButton btn = new JButton(numberBtnAction);
         Action pressBtnAction = new PressButtonAction(btn);
         InputMap inMap = btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
         ActionMap actionMap = btn.getActionMap();

         KeyStroke keyStroke = KeyStroke.getKeyStroke(numberString.charAt(0));
         inMap.put(keyStroke, NUMBER_TEXTS[i]);
         //!! actionMap.put(NUMBER_TEXTS[i], numberBtnAction);
         actionMap.put(NUMBER_TEXTS[i], pressBtnAction);

         add(btn);
      }

   }

   private class NumberBtnAction extends AbstractAction {
      public NumberBtnAction(String numberString, String numberText) {
         super(numberString);
         putValue(ACTION_COMMAND_KEY, numberText);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         System.out.println(e.getActionCommand());
      }
   }

   private class PressButtonAction extends AbstractAction {
      private AbstractButton btn;

      public PressButtonAction(AbstractButton btn) {
         this.btn = btn;
      }


      @Override
      public void actionPerformed(ActionEvent e) {
         btn.doClick();
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Foo2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Foo2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

答案 1 :(得分:2)

激活的内容有所不同。当您按下按钮时,该按钮已被激活,因此它actionCommand已作为ActionEvent

的一部分播种

1 键时,与键绑定关联的Action已激活,并且正在使用您提供的文本actionCommand

如果你想对两者使用相同的动作,那么将Action播种到键绑定和按钮......

MyAction myaction = new MyAction("1");
JButton b = new JButton(myaction);
b.setAction(myaction);
b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
b.getActionMap().put("one", myaction);

这样,当按下按钮或按下kbd&gt; 1键时,它将使用相同的Action ...这就是Action s

的重点

<强>更新

  

由于某种原因,它仍然没有解决它。我得到了相同的输出

好吧,我不确定你在做什么,但对我来说效果很好......

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestAction {

    public static void main(String[] args) {
        new TestAction();
    }

    public TestAction() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton b = new JButton("1");
            MyAction myaction = new MyAction("1");
            b.setAction(myaction);
            b.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "one");
            b.getActionMap().put("one", myaction);
            //b.setActionCommand("one");
            b.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(e.getActionCommand());
                }
            });

            add(b);
        }

    }

    class MyAction extends AbstractAction {

        public MyAction(String text) {
            super(text);
            putValue(ACTION_COMMAND_KEY, "one");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Action command is: " + e.getActionCommand());
        }
    }

}

<强>更新

根据评论中的关联示例,您将putValue(ACTION_COMMAND_KEY, "one");添加到MyAction课程,无论动作如何触发,都会打印one

事实上,我完全摆脱了按钮上的setActionCommand电话。

事实上,当使用Action时,我甚至不打扰动作命令,因为Action是自包含的,这是什么意思......