I'm creating a java swing application. The window has several buttons, and I would like the user to use the tab key to switch between buttons, and then press enter to activate the selected button.
I've created a sample window below. It has two buttons and a label, and activating either button changes the text of the label.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.UIManager;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ButtonTest
{
private JFrame frame;
// Create the application.
public ButtonTest() { initialize(); }
// Initialize the contents of the frame.
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblText = new JLabel("Text");
lblText.setBounds(167, 59, 46, 14);
frame.getContentPane().add(lblText);
JButton btnRed = new JButton("Red");
btnRed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblText.setText("Red");
}
});
btnRed.setBounds(74, 174, 89, 23);
frame.getContentPane().add(btnRed);
JButton btnBlue = new JButton("Blue");
btnBlue.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lblText.setText("Blue");
}
});
btnBlue.setBounds(220, 174, 89, 23);
frame.getContentPane().add(btnBlue);
}
// Launch the application.
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
ButtonTest window = new ButtonTest();
window.frame.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
}
When I run this code, I can press tab to switch between buttons, and pressing space while one of the buttons is focused activates it. I would prefer to press enter instead of space to activate the focused button. I've seen other answers on this site that use the following line of code to fix this issue:
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
This works on Windows, but it doesn't seem to work on Macs. On Macs, pressing space still works, and pressing enter still does nothing. Is there a solution that works on both platforms? (Note: to run this application on a Mac, I first export it to a runnable jar file.)
You can use Key Bindings
to bind the existing Action
to a different KeyStroke
for a single button:
InputMap im = button.getInputMap();
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );
or for all buttons in your application.
InputMap im = (InputMap)UIManager.get("Button.focusInputMap");
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );
See: Enter Key and Button for more information.