Page 1 of 1

Java Key Binding Tutorial and Demo Program Rate Topic: -----

#1 GregBrannon  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2205
  • View blog
  • Posts: 5,239
  • Joined: 10-September 10

Posted 27 August 2011 - 12:32 PM

*
POPULAR

Tutorial on Java Key Bindings

Introduction:
Though I often refer others to Sun/Oracle's Java tutorials and use them frequently myself, I occasionally hear complaints that the tutorials are unfriendly and hard to understand. I hadn't had a similar experience with the tutorials myself until I recently tried to use them to understand Key Bindings. The examples provided by the Sun/Oracle tutorials were over-complicated, clouding the actual Key Binding mechanics, and contained references to other tutorials that were important to understanding Key Bindings but were not provided in a way that showed their relationship to Key Binding. In effect, there seemed to be critical pieces missing in the way the fairly simple concept of Key Bindings was presented.

This tutorial is the result of 2 days of struggle with the Sun/Oracle tutorials and other sources from the web that were not much better. In fact, I don't cite any other sources. While I may have looked at other sources, any contributions they may have made to my eventual understanding of Java Key Bindings were purely accidental. Along the path to Key Binding enlightenment, the thought crossed my mind that this could be a good tutorial topic, but after I'd completed the 2-day struggle, I thought, "What was the big deal?" and criticized myself soundly for being so dense. Even so, I decided that completing the tutorial might help someone similarly affected with a Key Bindings block.

References:
Here's a link to the Sun/Oracle Tutorial on Key Binding:
http://download.orac...keybinding.html

I also used the following Sun/Oracle Tutorial, "How to Use Actions:"
http://download.orac...isc/action.html

Purpose of Key Bindings:
Paraphrased from the Sun/Oracle Tutorial on Key Bindings: the purpose of Key Binding is to provide a way of programming responses to individual keys typed by a user. Some examples of when key bindings are appropriate:
- To provide keyboard access to custom component. For example, you might want the custom component to react when it has the focus and the user presses the Space key,
- To override the behavior of an existing key binding. For example, if your application normally reacts to the F2 key in a particular way, you might want it to perform a different action or ignore the key press entirely.
- You want to provide a new key binding for an existing action. For example, you might feel strongly that Control-Shift-Insert should perform a paste operation.

The Code in the Key Binding Demo:
The code provided below is heavily commented, adequately explaining the Key Binding example, but the following highlights are provided:

Lines 47 - 59, method main(): The main() method creates a simple JFrame, mainFrame, to which a JPanel, created in the makePanel() method, is added to provide the functionality needed to show the Key Binding demo. When the program is first run, the mainFrame will display an empty JTextField and a single JButton, "Enter." The JTextField initially has focus so that keyboard presses will result in data being entered into the JTextField. If the Enter key is pressed or the Enter button is selected, the JTextArea will request focus and any data entered into the JTextField will be selected or highlighted. Since any additional data typed will replace the existing data in the JTextField, this feature provides the program a way to easily accept multiple values from the user without requiring his or her hands to leave the keyboard.

Lines 61 - 95 contain the makePanel() method which creates the JPanel, mainPanel, that will be shown in the demo's mainFrame. In addition to the JTextField and the JButton, the makePanel() method creates an ActionListener, buttonListener, and an Action, enterAction. buttonListener is added to the JButton, and enterAction is used to define what will happen when the Enter key is pressed. Then, most importantly, makePanel() provides the glue that binds a key press to a component of the JPanel, but which component?

One might think that since the program's reaction to a press of the Enter key is to be the same as its reaction to selecting the JButton, Enter, then the Key Binding should occur between the Enter key and the Enter button, but that's not the case. Since the JTextArea has the program's focus except for the very short time that the JButton is pressed, the Key Binding is actually established between the JTextArea and the Enter key. Then when the Enter key is pressed, the program can react as though the JButton, Enter, had been selected.

The real work of binding a key to the component occurs in lines 78 and 83. Line 78 retrieves the JTextField's Input Map and adds an entry for the Enter key called, "doEnterAction." Then line 83 retrieves the component's Action Map and pairs "doEnterAction" to the Action, enterAction. As I note in the comment preceding line 88, the single statement, dataField.setAction( enterAction ); results in the same effect as lines 78 and 83, but this approach is limited to a single pairing of an Action to the component in addition to any ActionListeners that may be added to the component.

Lines 99 - 113 define the class EnterAction. An instance of this class is used to specify what what happens when the Enter key is pressed. Line 105 sends the String "The Enter key has been pressed" to the standard output, and line 109 stimulates the JButton, enterButton, to react as though it had been pressed by calling the doClick() method. In this way, the response to the Enter key is exactly the same as clocking on the enterButton, with the exception of the output to the console.

Lines 117 - 132 define the ButtonListener. An instance of this class is added to the JButton, enterButton, to specify what is to happen when the button is clicked. Line 123 sends a message to the standard output to let the user know that the button was clicked. Line 127 requests that focus be returned to the JTextField from the JButton, and Line 128 selects the text existing in the JTextField.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

/*  File: KeyBindingExample.java
 *  
 *  Description: This class was created to provide a simple example of the
 *               application of KeyBinding to a Swing component. In this
 *               example, a JTextField and JButton are displayed on a JPanel in
 *               a JFrame. When the the focus is on the JTextField and an Enter
 *               key is pressed, the JButton action will occur as though the
 *               button had been pressed.
 *               
 *               The behavior shown in this simple example:
 *               1.  When the window first appears, the text field has focus.
 *                   Any keys typed will be entered as data in the text field;
 *               2.  Pressing Enter while the text field has focus will cause
 *                   the data typed to be selected so that any additional typing
 *                   will replace the existing. this behavior is useful for
 *                   multiple entries; and 
 *               3.  If the user presses the Enter button, focus is immediately
 *                   transferred back to the text field and the data in the 
 *                   field is selected.  
 *
 *  Source: Java Tutorials and Swing component APIs as needed. 
 *
 *  Author: GregBrannon, August 2011
 */
public class KeyBindingExample
{
    private static JFrame mainFrame;
    private static JTextField dataField;
    private static JButton enterButton;
    private static JPanel mainPanel;
    private static Action enterAction;
    private static ButtonListener buttonListener;
    
    // the main() method creates a simple JFrame to demonstrate the
    // key binding of the enter key to the component button "enter" 
    public static void main( String[] args )
    {
        mainFrame = new JFrame( "Key Binding Example" );

        mainFrame.add( makePanel() );
        mainFrame.setLocationRelativeTo( null );
        mainFrame.setSize( 200, 100 );
        mainFrame.setResizable( false );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        
        mainFrame.setVisible( true );

    } // end method main()
    
    static JPanel makePanel()
    {
        // declares the components used to create the JFrame's content and
        // the actions that will occur when the enter button is selected
        mainPanel = new JPanel();
        buttonListener = new ButtonListener();
        dataField = new JTextField( 15 );
        enterButton = new JButton( "Enter" );
        enterButton.addActionListener( buttonListener );
        
        // defines an AbstractAction item that will program the action to occur
        // when the enter key is pressed
        enterAction = new EnterAction();

        // the following two lines do the magic of key binding. the first line
        // gets the dataField's InputMap and pairs the "ENTER" key to the
        // action "doEnterAction" . . .
        dataField.getInputMap().put( KeyStroke.getKeyStroke( "ENTER" ),
                "doEnterAction" );

        // . . . then this line pairs the AbstractAction enterAction to the
        // action "doEnterAction"
        dataField.getActionMap().put( "doEnterAction", enterAction );

        // the following commented line 'seems' to have the same affect as the
        // two previous lines. this may be an acceptable approach when only a  
        // single action is required.
        // dataField.setAction( enterAction );
        
        // add the components to the JPanel and return the completed product
        mainPanel.add( dataField );
        mainPanel.add( enterButton );
        
        return mainPanel;
    }

    // class EnterAction is an AbstractAction that defines what will occur
    // when the enter key is pressed. 
    static class EnterAction extends AbstractAction
    {
        public void actionPerformed( ActionEvent tf )
        {
            // provides feedback to the console to show that the enter key has
            // been pressed
            System.out.println( "The Enter key has been pressed." );
            
            // pressing the enter key then 'presses' the enter button by calling
            // the button's doClick() method
            enterButton.doClick();
            
        } // end method actionPerformed()
        
    } // end class EnterAction
    
    // class ButtonListener defines the action to occur when the enter button
    // is pressed
    static class ButtonListener implements ActionListener
    {
        public void actionPerformed( ActionEvent bp )
        {
            // provides feedback to the console to show that the enter button
            // was pressed
            System.out.println( "The enter button was pressed." );

            // focus must be returned to the text field in order for the
            // selectAll() method to work.
            dataField.requestFocusInWindow();
            dataField.selectAll();
            
        } // end method actionPerformed()
        
    } // end class ButtonListener

} // end class KeyBindingExample



And that's it. If you run the program, you'll see that pressing the Enter key and clicking the Enter button have exactly the same effect, except you'll see different results in your standard output to reflect which control was activated. Now that you see how simple it is, I'm sure you're wondering, "What's the big deal?" I admit it, I'm a little slow.

Things to try or do to increase your knowledge:

1. Add a key binding to a Swing component in one of your existing designs.
2. Replace an existing "standard" key binding in one of your existing designs. For example, replace Ctrl-X as the standard "Cut" command for a text component with another key combination of your choosing.
3. Research the JComponent's 3 Input Maps and single Action Map and understand when each applies.
4. Find and bookmark a list of keystroke names as a ready reference.

Let me know if you have any questions or comments.

Is This A Good Question/Topic? 7
  • +

Replies To: Java Key Binding Tutorial and Demo Program

#2 Sheph  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 432
  • View blog
  • Posts: 1,020
  • Joined: 12-October 11

Posted 04 March 2012 - 04:39 PM

Thanks for the tutorial, Greg! Believe it or not, I had the exact same "Key Bindings Block" from reading the sun website. You explained the reason behind it in words I couldn't articulate to myself. I'm glad it was not just me. You're tutorial simplified it for me, so thank you.

Off Topic:
Spoiler

Was This Post Helpful? 0
  • +
  • -

#3 shellback3  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 19-August 12

Posted 19 August 2012 - 02:08 PM

Good tutorial!

I'm attempting to design a GUI and, in addition to key bindings and actions for some components, I need some that are *global* and can be used from anywhere on the form such as alt-P and alt-R to pause and start recording data (respectively) for all connected devices. I don't see how to set this up. My formMain has a content pane.

It's going to be used on an aircraft that has a really hard to use "mouse" control and it is often quite bumpy so the operator wants key combinations at least for all the common operations.

Thanks

Nate
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1