2011-12-21 76 views
4

我使用以下代码为使用swing的java窗体创建热键。如果按ALT + N,ALT + R,ALT + 1,ALT + 2,光标会移动到正确的文本字段,并在相应的文本字段中输入值。它正常工作。我的问题是,我保存并退出JButtons在这种形式如果。我按CTRL + S意味着同时选择保存按钮如果我按CTRL + X意味着退出按钮将被选中。如何为JButton创建助记符?如何使用以下代码执行CTRL + S,CTRL + X?使用swing在java中创建JButton的热键

在此先感谢。

package hotkeys; 
import java.awt.event.*; 
import javax.swing.*; 
import java.net.*; 
public class hotkey extends JFrame { 
    public static void main(String arg[]) { 
     JLabel Name = new JLabel("Name"); 
     JTextField tf1 = new JTextField(20); 
     Name.setLabelFor(tf1); 
     Name.setDisplayedMnemonic('N'); 


     JLabel Regno = new JLabel("RegNO"); 
     JTextField tf2 = new JTextField(20); 
     Regno.setLabelFor(tf2); 
     Regno.setDisplayedMnemonic('R'); 

     JLabel Mark1 = new JLabel("Mark1"); 
     JTextField tf3 = new JTextField(20); 
     Mark1.setLabelFor(tf3); 
     Mark1.setDisplayedMnemonic('1'); 

     JLabel Mark2 = new JLabel("Mark2"); 
     JTextField tf4 = new JTextField(20); 
     Mark2.setLabelFor(tf4); 
     Mark2.setDisplayedMnemonic('2'); 


     JButton b1 = new JButton("Save"); 
     JButton b2 = new JButton("eXit"); 


     JFrame f = new JFrame(); 
     JPanel p = new JPanel(); 

     p.add(Name); 
     p.add(tf1); 
     p.add(Regno); 
     p.add(tf2); 
     p.add(Mark1); 
     p.add(tf3); 
     p.add(Mark2); 
     p.add(tf4); 
     p.add(b1); 
     p.add(b2); 

     f.add(p); 
     f.setVisible(true); 
     f.pack(); 
    } 
} 
+2

请你有什么别的需要,没有任何进展??? HTTP://计算器。com/questions/8586353/create-hot-keys-in-java-using-swing,http://stackoverflow.com/questions/8585544/enter-key-using-in-jtextfield-java,http:// stackoverflow。 com/questions/8584998/hotkeys-creation-for-java-swing-form, – mKorbel 2011-12-21 10:15:05

回答

18

您需要在按钮的组件inputmap中注册一个keyBinding。在代码(重复的,你已被告知在你前面的问题做:-)

// create an Action doing what you want 
Action action = new AbstractAction("doSomething") { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("triggered the action"); 
    } 

}; 
// configure the Action with the accelerator (aka: short cut) 
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S")); 

// create a button, configured with the Action 
JButton toolBarButton = new JButton(action); 
// manually register the accelerator in the button's component input map 
toolBarButton.getActionMap().put("myAction", action); 
toolBarButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
     (KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "myAction"); 
+0

by anonymous top-voter – mKorbel 2011-12-21 10:25:05

9

太阳有一个非常好的全键绑定问题说明什么微妙的变体。你可以在这里找到它:

JavaSE Tutorial on Keybinding

//编辑

编辑我的例子代码,以便你可以复制粘贴+它,它会工作。包括缺少的点,谢谢你的反馈。

KeyStroke keySave = KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK); 
Action performSave = new AbstractAction("Save") { 
    public void actionPerformed(ActionEvent e) {  
     //do your save 
     System.out.println("save"); 
    } 
}; 
JButton b1 = new JButton(performSave); 
b1.getActionMap().put("performSave", performSave); 
b1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keySave, "performSave"); 

KeyStroke keyExit = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK); 
Action performExit = new AbstractAction("Exit") { 
    public void actionPerformed(ActionEvent e) {  
     //exit 
     System.out.println("exit"); 
    } 
}; 
JButton b2 = new JButton(performExit); 
b2.getActionMap().put("performExit", performExit); 
b2.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyExit, "performExit"); 
+0

好方向 - 只是有点不完整:另外你需要a)在按钮的actionMap中注册动作b)如果你想要一个窗口范围的快捷方式,将keyStroke注册到“component inputMap”中,这是JComponent.WHEN_IN_FOCUSED_WINDOW类型的一个,而不是默认的(这是WHEN_FOCUSED) – kleopatra 2011-12-21 10:33:47

+0

只是注意到c)Action应该有它的名字属性设置(而不是实例化按钮与文本) - 所以现在downvoted,将恢复一旦你纠正小问题:-) – kleopatra 2011-12-21 10:46:11

+0

感谢您的反馈kleopatra。 :)我现在编辑了代码示例,以便在复制粘贴之后工作。祝你有美好的一天。 – Matschie 2011-12-21 13:44:47

1

刚修改您的代码。 (插入代码// **
只需要1条评论... Ctrl-X是编辑命令“剪切”的快捷方式(与Ctrl-C一起使用)(Ctrl-C与Ctrl-C & Ctrl-V一起)。你在框架中有可编辑的字段。我使用了Ctrl-Q(退出)。

import java.awt.event.*; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 
import javax.swing.plaf.ActionMapUIResource; 

import java.net.*; 

public class HotKeys extends JFrame { 
public static void main(String arg[]) { 
    JLabel Name = new JLabel("Name"); 
    JTextField tf1 = new JTextField(20); 
    Name.setLabelFor(tf1); 
    Name.setDisplayedMnemonic('N'); 

    JLabel Regno = new JLabel("RegNO"); 
    JTextField tf2 = new JTextField(20); 
    Regno.setLabelFor(tf2); 
    Regno.setDisplayedMnemonic('R'); 

    JLabel Mark1 = new JLabel("Mark1"); 
    JTextField tf3 = new JTextField(20); 
    Mark1.setLabelFor(tf3); 
    Mark1.setDisplayedMnemonic('1'); 

    JLabel Mark2 = new JLabel("Mark2"); 
    JTextField tf4 = new JTextField(20); 
    Mark2.setLabelFor(tf4); 
    Mark2.setDisplayedMnemonic('2'); 

    JButton b1 = new JButton("Save"); 
    JButton b2 = new JButton("eXit"); 

    JFrame f = new JFrame(); 
    JPanel p = new JPanel(); 

    p.add(Name); 
    p.add(tf1); 
    p.add(Regno); 
    p.add(tf2); 
    p.add(Mark1); 
    p.add(tf3); 
    p.add(Mark2); 
    p.add(tf4); 
    p.add(b1); 
    p.add(b2); 

    // ***************************************************** 
    ActionMap actionMap = new ActionMapUIResource(); 
    actionMap.put("action_save", new AbstractAction() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("Save action performed."); 
     } 
    }); 
    actionMap.put("action_exit", new AbstractAction() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("Exit action performed."); 
     } 
    }); 

    InputMap keyMap = new ComponentInputMap(p); 
    keyMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, 
      java.awt.Event.CTRL_MASK), "action_save"); 
    keyMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, 
      java.awt.Event.CTRL_MASK), "action_exit"); 
    SwingUtilities.replaceUIActionMap(p, actionMap); 
    SwingUtilities.replaceUIInputMap(p, JComponent.WHEN_IN_FOCUSED_WINDOW, 
      keyMap); 
    // ***************************************************** 

    f.add(p); 
    f.setVisible(true); 
    f.pack(); 
} 
} 
+0

@ java872这里回答你的问题,回答为http://meta.stackexchange.com/questions/16721/how-does-accept-rate-work/65088#65088 +1 – mKorbel 2011-12-21 11:15:36

+0

no - 你_never_(阅读:除非你真的打算:-)想要使用这些replaceXX方法。 a)你为JPanel的所有实例安装了这些新地图 - 至少是ActionMap b)没有经过LAF – kleopatra 2011-12-21 12:01:05

+0

的切换,但对我的最后一条评论稍作修改:b)不正确,因为XXPanelUI根本没有安装任何地图 – kleopatra 2011-12-21 12:27:07

0

对于我来说,我和其他人一样对我提供了这样的学习体验。我一直很难应用代码片段来处理我在过去发现的键绑定,我希望我的解释和代码能够清楚。感谢@kleopatra为她的代码片段,我在下面的代码基础上。

(我用大写字母,我应该不是为了更清楚地显示哪些必须匹配。)

代码通过匹配字符串链接Ctrl-Shift-U按键在actionPerformed代码为MYACTIONgetInputMapgetActionMap

下面的三个实例MYACTION必须匹配,必须与MYACTIONBUTTON的四个实例匹配,因为字符串MAKE_THESE_MATCH的两个实例必须匹配。给他们打电话,只是让他们匹配。

按钮MYACTIONBUTTON必须具有MYACTION作为参数传递给JButton定义它,并且必须具有施加到它getInputMapgetActionMap

private static JButton MYACTIONBUTTON; 
private static JFrame frame; 
private static JPanel panel; 

...

Action MYACTION = new AbstractAction() 
{ 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     // put action code here 
    } 
}; 

MYACTIONBUTTON = new JButton(MYACTION); 

MYACTIONBUTTON.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) 

          .put(getKeyStroke(VK_U, CTRL_DOWN_MASK | SHIFT_DOWN_MASK), 

            "MAKE_THESE_MATCH"); 

MYACTIONBUTTON.getActionMap().put("MAKE_THESE_MATCH",  MYACTION); 

panel.add(MYACTIONBUTTON); 

frame.add(panel);