Everything is okay until user choose a some value from list and than press key ENTER then my panel goes to next Step 3. I attach a key
listener to list something like [...]
If you want Enter key in your list has precedence over the default Next -> button then you have to use Key binding to attach an action to your list when it's focused:
KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
Action updateTextfieldAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
JList list = (JList)evt.getSource();
Object selectedPackage = list.getSelectedValue();
typePackageField.setText((String)selectedPackage );
}
};
list = new JList(new PackagesListModel());
list.getInputMap().put(enterKeyStroke, "enter");
list.getActionMap().put("enter", updateTextfieldAction);
Note that getInputMap() is a shortcut for getInputMap(JComponent.WHEN_FOCUSED). This means that if your list has focus and Enter key is pressed, then the action attached to this key stroke will be performed.
By this way your action will always have precedence over the next button's action, either if this button is the default button or it has attached an action using key bindings using WHEN_IN_FOCUSED_WINDOW
like this:
JButton button = new JButton(nextStepAction);
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, "enter");
button.getActionMap().put("enter", nextStepAction);
Where nextStepAction
would be the action to go to wizard's next step.
See also Key bindings vs. key listeners in Java
Example
Please cosider the example below. Note if you focus another component but list the the default action is performed. I've set the button as frame's root pane default button and I've attached an action using WHEN_IN_FOCUSED_WINDOW
just to prove that WHEN_FOCUSED
action has precedence over those.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Demo {
private JList list;
private JTextField textField;
private void createAndShowGUI() {
KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
Action nextStepAction = new AbstractAction("Next") {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Going to step 3!", "Message", JOptionPane.INFORMATION_MESSAGE);
}
};
Action updateTextfieldAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
textField.setText((String)list.getSelectedValue());
}
};
list = new JList(new String[]{"Item 1", "Item 2", "Item 3"});
list.setPrototypeCellValue("This is a list's prototype cell value.");
list.getInputMap().put(enterKeyStroke, "enter");
list.getActionMap().put("enter", updateTextfieldAction);
textField = new JTextField(15);
JPanel listPanel = new JPanel();
listPanel.add(new JScrollPane(list));
listPanel.add(textField);
JButton button = new JButton(nextStepAction);
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, "enter");
button.getActionMap().put("enter", nextStepAction);
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonsPanel.add(button);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(listPanel);
frame.add(buttonsPanel, BorderLayout.PAGE_END);
frame.getRootPane().setDefaultButton(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
Other comments
Please note that if you want avoid all this matter, you could attach a ListSelectionListener to your list and update the text field on selection change with no need to press Enter key at all. In fact if you have access to the next step action you could enable/disable it based on list selection. By doing this you'll be sure that wizard can't continue if no item is selected in your list. IMHO that would be a more elegant way to handle this situation. See Selecting Items in a List for further details.