Reputation: 37
I have been wracking my brain over this for a while now. When I run the following code, any other key works correctly, on invoking the showPopup() method of the JComboBox, but whenever one presses enter, nothing happens. I have tried to fire mouse events to simulate the user physically clicking on the JComboBox, but nothing has so far worked. (I could use a java.awt.Robot, but I would really prefer not to.). Here is an example program, which simply shows a JComboBox, and adds a KeyAdapter to it:
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SpringLayout;
public class Test {
public static void main(String[] args) {
JFrame testFrame = new JFrame();
testFrame.setLocationRelativeTo(null);
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout layout = new SpringLayout();
testFrame.getContentPane().setLayout(layout);
JComboBox testingComboBox = new JComboBox(new String[] {"Option 1", "Option 2", "Option 3"});
testingComboBox.addKeyListener(new KeyAdapter(){
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
testingComboBox.showPopup();
} else if (e.getKeyCode() == KeyEvent.VK_2){
testingComboBox.showPopup();
}
}
});
testFrame.add(testingComboBox);
layout.putConstraint(SpringLayout.NORTH, testingComboBox, 0, SpringLayout.NORTH, testFrame);
layout.putConstraint(SpringLayout.WEST, testingComboBox, 0, SpringLayout.WEST, testFrame);
testFrame.pack();
testingComboBox.requestFocusInWindow();
int differenceInWidth = testFrame.getWidth() - testFrame.getContentPane().getWidth();
int differenceInHeight = testFrame.getHeight() - testFrame.getContentPane().getHeight();
testFrame.setMinimumSize(new Dimension(testingComboBox.getWidth() + differenceInWidth, testingComboBox.getHeight() + differenceInHeight));
testFrame.setVisible(true);
}
}
I'm not quite sure what's going on, and would appreciate any possible help.
Note: I have also tried using an ActionListener, and that would also provide the same problem. If I put a System.out.println("Test");
right before the showPopup() call, "Test" is still printed in the command line, but nothing appears.
Upvotes: 2
Views: 1516
Reputation: 324207
Swing was designed to be used with Key Bindings.
The Enter
key is already defined as a binding for the JComboBox
, so that action is basically causing the popup to be closed. This can be demonstrated by using:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
testingComboBox.showPopup();
}
});
By using the invokeLater() the code is placed at the end of the EDT so it executes after the default Enter key processing.
So in reality you should not be trying to listen for Enter key events since they are already handled by the UI.
Check out Key Binding Defaults for a list of the default key bindings for each component.
When you look at the list you will notice that a combo box already has an Action to toggle the popup, so if you do create a Key Binding you should use the existing Action. The above link shows you how to do this:
KeyStroke ks = KeyStroke.getKeyStroke("2");
InputMap im = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(ks, "togglePopup");
Upvotes: 2
Reputation: 14826
Don't use KeyListener
. Use Key Bindings instead. This should work:
testingComboBox.getInputMap().put(KeyStroke.getKeyStroke("ENTER"),
"showPopup");
testingComboBox.getActionMap().put("showPopup",
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
testingComboBox.showPopup();
}
});
Upvotes: 2