Java Tips Weblog

  • Blog Stats

    • 2,571,468 hits
  • Categories

  • Archives

Enter Key and Button

Posted by Rob Camick on October 25, 2008

A JButton that has focus can be activated by using the space bar. However, on any given Window a single button can be designated as the “Default Button” for the Window. The default button is noticeable by the darker border around the button. The default button can be activated by using the Enter key, even when it doesn’t have focus.

To assign an initial default button to a JFrame or JDialog you can use:

getRootPane().setDefaultButton(...);

In Windows Look and Feel, when you tab to a button it temporarily becomes the default button. In this case, you can then activate the button either by using the space bar or the Enter key. When you tab off the button, the original default button is reset. However, in the Metal Look and Feel, the default button never changes. Therefore, even when a button has focus you can still only activate the button using the space bar.

Many users are more familiar with the Windows approach and would like the Metal LAF to work that way as well. That is, they would like to be able to activate a button that has focus with the Enter key. The solution to this problem will depend on the version of Java you are using.

The JDK5 release added support for this functionality. You can activate this functionality simply by adding a property to the UIManager. The property to be set is shown in the following line of code:

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);

Prior to JDK5 you have a couple of choices:

  • use key bindings to map the space bar Actions to the Enter key
  • reset the default button for the root pane as a button gains focus

Although using key bindings is easier it does not really solve the problem completely. Yes, it will allow you to invoke the button by using the Enter key, but the border of the button doesn’t change to let you know it is the default button. This can be confusing to users. For this reason, I recommend the second approach which is discussed in more detail next.

In order to make a button the default button you need to know when a button gains focus. You could add a FocusListener to every button, but this would be extremely tedius. Fortunately there is an easier way. We can add a PropertyChangeListener to the KeyboardFocusManager and listen for focus change events. Using this approach all focus changes are handled in one place so all we need to do is manage focus changes that involve buttons. The DefaultButtonListener class will manage all this for you. You can use this class in your application with the following line of code:

DefaultButtonListener listener = DefaultButtonListener.install();

The remainder of this entry will look at the key bindings approach. I suggest you start by reading my entry on Key Bindings and play with the related application. Once you do this you will notice that a button has two default Actions, “pressed” and “released” which are mapped to the space bar. Therefore, if we want to activate the button using the Enter key, we just need to map the Enter key to the same Actions:

InputMap im = button.getInputMap();
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );

The problem with this approach is that it only works for a single button. Chances are you will want this behaviour for all buttons in your application. Now, I suggest you read my entry on UIManager Defaults and play with the related application. Once you do this you will notice the “Button.focusInputMap” property. This will return the InputMap that is shared for all buttons. Therefore, if we do the same mapping we did above, it will be in effect for all buttons created after the input map was changed:

InputMap im = (InputMap)UIManager.get("Button.focusInputMap");
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );

Get The Code

DefaultButtonListener.java

See Also

Key Bindings
UIManager Defaults

Related Reading

How to Write a Property Change Listener
Java API: java.awt.KeyboardFocusManager
Java API: javax/swing/JRootPane.setDefaultButton(…)

6 Responses to “Enter Key and Button”

  1. Andre Uhres said

    “Enter Key and Button” is wrongly posted under “Classes”. The right category is “Tips” where it already appears!

  2. Rob Camick said

    This entry actually has three suggested solutions. I considered two to be “Tips” because they use a UIManager property or manual coding the update the InputMap.

    The other one is the solution that uses the DefaultButtonListener class, which is activated by using a single line of code. So I feel this last solution falls under the “Classes” category since the code is self contained and can be used in any Swing app. My “About” page attempts to explain the difference between tips and classes.

  3. S.J Evan said

    What are they talking about? :|

  4. Anonymous said

    Thank you!

Leave a comment