Reputation: 811
I have a class implementing a KeyListener
to collect a list of pressed keys. The list is then delegated to an instance of KeyListener
to be handled. Each time a key is released, it must be removed from the list.
My issue is that they are not being removed from the list because the KeyEvent
I store in the list when pressed is not the same as the KeyEvent
generated when the Key is released. This results in none of the KeyEvents being removed and thus, they accumulate.
What changes must I make to ensure that I can remove a KeyEvent
with only knowledge of a different KeyEvent
for the same key (the remove method checks with .equals()
)?
KeyListener subject;
ArrayList<KeyEvent> pressed = new ArrayList<KeyEvent>();
public MultiKeyListener(KeyListener subject) {
this.subject = subject;
}
@Override
public void keyPressed(KeyEvent k) {
pressed.add(k);
if (subject != null && pressed.size() > 0) {
for (int i = 0; i < pressed.size(); i++) {
subject.keyPressed(pressed.get(i));
}
}
}
@Override
public void keyReleased(KeyEvent k) {
pressed.remove(k);
if (subject != null && pressed.size() > 0) {
for (int i = 0; i < pressed.size(); i++) {
subject.keyPressed(pressed.get(i));
}
}
}
@Override
public void keyTyped(KeyEvent k) {
}
Upvotes: 1
Views: 564
Reputation: 904
Use a wrapper around KeyEvent.
public class KeyEventWrapper
{
private KeyEvent keyEvent;
public KeyEventWrapper(KeyEvent keyEvent)
{
this.keyEvent = keyEvent;
}
public KeyEvent getKeyEvent()
{
return keyEvent;
}
public boolean equals(Object object)
{
if(object instanceof KeyEventWrapper)
{
KeyEventWrapper wrapper = (KeyEventWrapper) (object);
KeyEvent k = wrapper.getKeyEvent();
return (this.keyEvent.getKeyCode() == k.getKeyCode());
}
return false;
}
public int hashCode()
{
return this.keyEvent.getKeyCode();
}
}
Now, you can use an ArrayList of this wrapper object instead of KeyEvent.
ArrayList<KeyEventWrapper> pressed = new ArrayList<KeyEventWrapper>();
...
pressed.add(new (KeyEventWrapper(k));
...
pressed.remove(new (KeyEventWrapper(k));
Upvotes: 1
Reputation: 19
I'd say you should iterate pressed List from the end to the start and remove the first occurrence of KeyEvent there that has the same KeyCode. Something like this:
@Override
public void keyReleased(KeyEvent k) {
for (int i=pressed.size()-1;i>=0;i--) {
if (pressed.get(i).getKeyCode()==k.getKeyCode()) {
pressed.remove(i);
break;
}
}
......
Upvotes: 1
Reputation: 418
You would want to be storing which Key is pressed, not the KeyEvent itself. A new event occurs every time a key is pressed, typed, or released. What you want to keep track of is either the KeyCode or KeyChar.
Edit: Just another suggestion, you might want to consider using a Set
instead of a List
to keep track of which keys have been pressed. A single key realistically cannot be pressed more than once.
Upvotes: 1