I would like to understand why the printed list index for this JLIST Object gets out of sync with the highlighted line when KeyPressedListener fires following up and down key press events, and how I might resolve the issue
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JList;
import java.awt.BorderLayout;
public class ListTest
{
private JFrame frame;
private String[] values = new String[] {"Line 0", "Line 1", "Line 2", "Line 3"};
public static void main(String[] args)
{
ListTest window = new ListTest();
window.frame.setVisible(true);
}
public ListTest()
{
frame = new JFrame();
frame.setBounds(100, 100, 136, 153);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JList<String> list = new JList<String>(values);
frame.getContentPane().add(list, BorderLayout.CENTER);
list.setSelectedIndex(0);
list.addKeyListener(new KeyListener()
{
@Override
public void keyReleased(KeyEvent arg0){}
@Override
public void keyTyped(KeyEvent arg0){}
@Override
public void keyPressed(KeyEvent e)
{
int code = e.getKeyCode();
switch( code )
{
case KeyEvent.VK_UP:
System.out.println("UP " + list.getSelectedIndex());
break;
case KeyEvent.VK_DOWN:
System.out.println("DOWN " + list.getSelectedIndex());
break;
}
}
});
}
}
Because the keyPressed
event will return the previous selection.
Just get the output from the keyReleased
event and you'll be fine.
public void keyReleased(KeyEvent arg0) {
int code = arg0.getKeyCode();
switch (code) {
case KeyEvent.VK_UP:
System.out.println("UP " + list.getSelectedIndex());
break;
case KeyEvent.VK_DOWN:
System.out.println("DOWN " + list.getSelectedIndex());
break;
}
}
Here's a better explanation of keyevents:
keyPressed()
: when the key goes down
keyReleased()
: when the key comes up
keyTyped()
: when the unicode character represented by this key is sent by the keyboard to system input
The selection of an item in JList
happens when the key comes up. When keyReleased
is fired the next item in JList
will already be selected. But the keyPressed
event fires before the selection happens.