简体   繁体   中英

Double Click Function for Key Listener using Arrays and Array lists in java counts everything as a double click

The java KeyListener class has no option for a double key press, so I attempted to make my own using multiple arrays and arraylists.

Here is the relevent code

    private ArrayList<Integer> ButtonsPressedChar = new ArrayList<Integer>();
    private ArrayList<Long> ButtonsPressedTimes = new ArrayList<Long>();
    private int[] PossiblePresses = new int[222];
    private ArrayList<Integer> DoublePresses = new ArrayList<Integer>();
    private ArrayList<Integer> ToBeRemovedChars = new ArrayList<Integer>();
    private ArrayList<Integer> ToBeRemovedTimes = new ArrayList<Integer>();     
    private Long LastTimeForDoublePress;
    private Long NowTime;
    private int PositionTime;
    private int PositionChar;

    public void DetectDoubleKeyPresses(){
        PositionTime = 0;
        PositionChar = 0;
        NowTime = System.currentTimeMillis();
        for(int temp : PossiblePresses){
            PossiblePresses[temp] = 0;                    
        }
        for(Long temp: ButtonsPressedTimes){
            if( temp - NowTime >= 300){
                ButtonsPressedChar.remove(PositionTime);
                ToBeRemovedTimes.add(PositionTime);
                System.out.println("removed");                         
            }
            PositionTime++;
        }
        for(int temp: ToBeRemovedTimes){
            ButtonsPressedTimes.remove(temp);
            System.out.println("DONE");
        }
        DoublePresses.clear();
        for(Integer temp: ButtonsPressedChar){
            System.out.println("hi 1");
            if( PossiblePresses[temp] == 0){
                System.out.println("First Press" + temp + PossiblePresses[temp]);
                PossiblePresses[temp] = 2;
            }
            else if(PossiblePresses[temp] == 2){
                DoublePresses.add(temp);
                System.out.println(ButtonsPressedChar.size());
                ToBeRemovedChars.add(temp);
                ButtonsPressedTimes.remove(PositionChar);
                System.out.println("DOUBLE PRESS" + temp.toString()+ PossiblePresses[temp]);
            }
            System.out.println("hi 2");
            PositionChar++;
        }
        for(Integer temp: ToBeRemovedChars){
            while(ButtonsPressedChar.contains(temp)){
                ButtonsPressedChar.remove(temp);
            }
            System.out.println("DONE");
        }
        ToBeRemovedChars.clear();
        LastTimeForDoublePress =NowTime;
    }

public class Keys implements KeyListener{
    @Override
    public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
        if(ButtonsHeld.contains(e.getKeyCode())){
            Integer tempInteger = new Integer(e.getKeyCode());
            ButtonsHeld.remove(tempInteger);
        }
        else 
            System.out.println("ERROR");               
        System.out.println(e.getKeyCode());
        ButtonsPressedChar.add( e.getKeyCode());
        ButtonsPressedTimes.add(System.currentTimeMillis())               
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(ButtonsHeld.contains(e.getKeyCode())){               
            System.out.println("Error: Attempted Key Press Twice, original press was not removed from ButtonsHeld");
        }     
        else if(!ButtonsHeld.contains(e.getKeyCode())){
            ButtonsHeld.add(e.getKeyCode());
        }
    }     

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
    }

    public ArrayList<Integer> ButtonsHeld = new ArrayList<Integer>();          
    public void KeyHeldChecker(){               
        }          
 }

I'm so sorry if some of the brackets are in weird places, i had to adjust everything to get it in the code block

Detect Double Key presses is executed 60 times a second. The 'hi 1' and 'hi 2' were just part of my debugging to see what was being executed. This is what is executed when J (key code 74) is pressed a single time:

74
hi 1
First press740
hi 2
hi 1
1
DOUBLE PRESS742
hi 2
DONE

At first i thought possible presses was not being cleared properly, but the for loop seems to be working. If anyone knows why this isn't working or even just a better way of doing this that would be amazing.

Sorry for the bad format, I honestly can't get it to work and are not finding any quadruple spaces anywhere they shouldn't be. I hope that it doesn't make it too hard to see or understand.

If you are wanting to detect a simple double press there is no real need for any arrays or Arraylists. You only need to really store the previous key press.

Consider this: If you press J then K then J the J is no longer a double press so why do you care about it.

To do this you could use the following:

public class DoubleKeyPressDetection
{
     // Below int is the number of milliseconds between the presses to determine 
     // if it was an intentional double press 
     // Adjust this for sensitivity required
    private static int doublePressSpeed = 500; // Half a second
    private static KeyEvent lastKeyEvent;

    public static  boolean isDoublePress(KeyEvent ke)
    {
        KeyEvent temp = lastKeyEvent;
        lastKeyEvent = ke;
        return temp != null
            && temp.getKeyCode() == ke.getKeyCode()
            && ((ke.getWhen() - temp.getWhen()) < doublePressSpeed);
    }
}

Then in your KeyListener

@Override
public void keyPressed(KeyEvent e)
{
    if(DoubleKeyPressDetection.isDoublePress(e))
        System.out.println("You have double pressed " + KeyEvent.getKeyText(e.getKeyCode()));
}

Points to note:

  • If you put this in both the keyPressed and keyReleased methods then it will action on every keyPress and release - so will not work correctly
  • If you use the keyTyped method then this might not work as the KeyEvent does not have the keyCode
  • Not all keys will be tracked by this (depending on your application ie Tab in a swing app)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM