Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create hot keys for JButton in java using swing

Tags:

java

swing

I use the following code to create hot keys for the java form using swing. If I press ALT+N,ALT+R,ALT+1,ALT+2 the cursor moves to correct text fields and I enter the value in corresponding Text Fields. It works properly. My problem is, I have Save and exit JButtons in this form if. I press CTRL+S means the Save button will be selected at the same time If i press CTRL+X means the exit button will be selected. How to create mnemonics for JButton? How to do CTRL+S,CTRL+X this using the following code?

Thanks in advance.

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();
    }
}
like image 798
java872 Avatar asked Dec 21 '11 10:12

java872


4 Answers

Just modified your code. (inserted code in //**)
Just 1 comment... Ctrl-X is shortcut for edit command "Cut" (along with Ctrl-C & Ctrl-V). You have editable fields in frame. I used Ctrl-Q (quit) instead.

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();
}
}
like image 40
andrey Avatar answered Nov 15 '22 08:11

andrey


I provide this as much for me as a learning experience as for anyone else. I've always had difficulty applying code snippets for key binding that I've found in the past and I hope my explanation and code will be clear. Thanks to @kleopatra for her code snippet, on which I base my code below.

(I'm using CAPITAL LETTERS where I should NOT in order to more clearly show what MUST MATCH.)

The code links the Ctrl-Shift-U keystroke to the code in actionPerformed for MYACTION via the matching strings in getInputMap and getActionMap.

The three instances of MYACTION below must match, as must the four instances of MYACTIONBUTTON, as must the two instances of the string MAKE_THESE_MATCH. Call them what you will; just make them match.

The button MYACTIONBUTTON must have MYACTION as the argument to the JButton defining it AND must have getInputMap and getActionMap applied to it.

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);
like image 44
DSlomer64 Avatar answered Nov 15 '22 08:11

DSlomer64


You need to register a keyBinding in the button's component inputmap. In code (repeating a subtle variant of what you have been told to do in your previous questions :-)

// 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");
like image 91
kleopatra Avatar answered Nov 15 '22 08:11

kleopatra


Sun has a really good Description of the whole Key Binding issue. You can find it here:

JavaSE Tutorial on Keybinding

//EDIT

Edited my example code so you can just copy + paste it and it will work. Included the points that were missing, thanks for the feedback.

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"); 
like image 23
Matschie Avatar answered Nov 15 '22 07:11

Matschie