[Java] Detect key pressed.

Nenad

~Choco Coronet~ Omnomnom
Reaction score
137
Well, looked around the interwebs and tried a few solutions nothing seems to work so far. I need to detect when a key is pressed, specifically the arrow keys. For now, I've got this method (There are other methods in but they have no relations with this one).

Code:
import java.awt.event.KeyEvent;
import acm.program.*;

public class Sokoban extends ConsoleProgram {
	
	int xpos = 0;
	int ypos = 0;
	char mc = '@';
	char hold = ' ';
	char[][] grid = new char[7][9]; //Creates the grid based of the Level base imaginary two dimensional array in comments.
	
	public void createlevel()
	 {
		String Levelbase = ("##########  $   .##  ##   ##  @   ###  #$$ ###  #. .###########"); 
		// "#########"         																						
		// "#  $   .#" 																						
		// "#  ##   #" 																						
		// "#  @   ##" 																						
		// "#  #$$ ##" 																						
		// "#  #. .##" 																						
		// "#########"
		
		int k = -1; //Counts characters in Level Base.
		for (int i=0; i<grid.length; i++)
		{
			for (int j=0; j<grid[i].length; j++)
			{
			k=k+1;	
			grid[i][j] = Levelbase.charAt(k);
			
			if (j == 8) //Prints out the level.
			{
				println(grid[i][j]);
			}
			
				else
				{
					print(grid[i][j]);
				}
			}
	     }
		xpos = 3; // Set x of main char;
		ypos = 3; // Set y of main char;
	  }
    public void keyPressed(KeyEvent e) {
	    int keyCode = e.getKeyCode();
	    switch( keyCode ) { 
	        case KeyEvent.VK_UP:
	        	
	        	 mc = grid[xpos][ypos];
		         hold = grid[xpos][ypos-1];
		         mc = grid[xpos][ypos-1];
		         hold = grid[xpos][ypos];
	        	
	            break;
	        case KeyEvent.VK_DOWN:
	        	
	        	 mc = grid[xpos][ypos];
		         hold = grid[xpos][ypos+1];
		         mc = grid[xpos][ypos+1];
		         hold = grid[xpos][ypos];
	        	
	            break;
	        case KeyEvent.VK_LEFT:
	        	
	            mc = grid[xpos][ypos];
	            hold = grid[xpos-1][ypos];
	            mc = grid[xpos-1][ypos];
	            hold = grid[xpos][ypos];
	            
	            break;
	        case KeyEvent.VK_RIGHT :

	        	 mc = grid[xpos][ypos];
		         hold = grid[xpos+1][ypos];
		         mc = grid[xpos+1][ypos];
		         hold = grid[xpos][ypos];
		         
	            break;
	     }
	} 
	
	public void run ()
	{
		createlevel();
	}
}

That is my entire code, and once again it would be helpful to explain what we're doing here. The main problem now is to get the actions keys to respond. Also, if anyone has any suggestions about improving the said code up top i don't mind that as well, but i would like to keep the focus on the main problem. Without this i won't really get far ^^

Edit: Oh and yeah, whenever i press a key nothing happens, i added a debugger before that prints a line but it doesn't activate, so my method does not in fact register the keys.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
That's not how it works. You never tell your program to bind any event. And KeyListener is for AWT and Swing, not console.

There's no way to hook the keyboard in Java, unless you use JNI

I had done it for a guy once but I can't find the thread.

EDIT: Oh there I find it..
http://www.thehelper.net/forums/sho...scape-Key-press-in-Java?p=1254842#post1254842
I don't think you could use SetWindowsHookEx because Java does not have a such thing as IntPtr (C#).

You also need to make a different Library for every OS your program's going to run on, since the Library contains OS calls.
 

UndeadDragon

Super Moderator
Reaction score
448
Keyboard events won't work in Console AFAIK.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Alright, I had some free time so I decided to just do it.

Only works with windows tho.

It basicly catches every single key that is pressed and generates an event with it.

boolean keydown:
true keydown
false keyup
int vk:
virtual key code

Code:
package test;

import javax.swing.JFrame;
import jhook.Keyboard;
import jhook.KeyboardListener;

/*
 * @Author: Simon
 */

public class Main {

    public static void main(String[] args) {
        new JFrame().setVisible(true); // Just so it stays Idle

        Keyboard kb = new Keyboard();
        kb.addListener(new KeyboardListener() {
            public void keyPressed(boolean keydown, int vk) {
                if (keydown && vk == Keyboard.VK_ESCAPE) {
                    System.exit(0); // The escape key will be catched from anywhere!!
                }
            }
        });

    }
}

Download and extract JHook.jar from the zip file attached below and add the jar to your project's build path. Use the code above to make what you want.
 

Nenad

~Choco Coronet~ Omnomnom
Reaction score
137
Thanks a lot for the time, however, still doesn't work. Doesn't register a keyboard event no matter what i do <.< . I guess i'll just have to try using the graphics program (which can detect key press easier ><).
 

Nenad

~Choco Coronet~ Omnomnom
Reaction score
137
Code:
package oving4;

import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import jhook.Keyboard;
import jhook.KeyboardListener;
import acm.program.*;

public class Sokoban extends ConsoleProgram {
	
	int xpos = 0;
	int ypos = 0;
	char mc = '@';
	char hold = ' ';
	char[][] grid = new char[7][9]; //Creates the grid based of the Level base imaginary two dimensional array in comments.
	
	public void createlevel()
	 {
		String Levelbase = ("##########  $   .##  ##   ##  @   ###  #$$ ###  #. .###########"); 
		// "#########"         																						
		// "#  $   .#" 																						
		// "#  ##   #" 																						
		// "#  @   ##" 																						
		// "#  #$$ ##" 																						
		// "#  #. .##" 																						
		// "#########"
		
		int k = -1; //Counts characters in Level Base.
		for (int i=0; i<grid.length; i++)
		{
			for (int j=0; j<grid[i].length; j++)
			{
			k=k+1;	
			grid[i][j] = Levelbase.charAt(k);
			
			if (j == 8) //Prints out the level.
			{
				println(grid[i][j]);
			}
			
				else
				{
					print(grid[i][j]);
				}
			}
	     }
		xpos = 3; // Set x of main char;
		ypos = 3; // Set y of main char;
	  }
	/*
	 * @Author: Simon
	 */

	public class Main {

	    public void main(String[] args) {
	        new JFrame().setVisible(true); // Just so it stays Idle

	        Keyboard kb = new Keyboard();
	        kb.addListener(new KeyboardListener() {
	            public void keyPressed(boolean keydown, int vk) {
	                if (keydown && vk == Keyboard.VK_ESCAPE) {
	                   print("aaaaaaaaaaaaaaaaaaaaa");
	                }
	            }
	        });

	    }
	}
	
	public void run ()
	{
		createlevel();
	}
}

Couldn't start it in the run method (error after error). Couldn't start it normally unless i took out static.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Ah, you did it wrong, you imported the class and everything.

This should work, althought I haven't tested it.
Code:
package oving4;

import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import jhook.Keyboard;
import jhook.KeyboardListener;
import acm.program.*;

public class Sokoban extends ConsoleProgram {
	
	int xpos = 0;
	int ypos = 0;
	char mc = '@';
	char hold = ' ';
	char[][] grid = new char[7][9]; //Creates the grid based of the Level base imaginary two dimensional array in comments.
	
	public void createlevel()
	 {
		String Levelbase = ("##########  $   .##  ##   ##  @   ###  #$$ ###  #. .###########"); 
		// "#########"         																						
		// "#  $   .#" 																						
		// "#  ##   #" 																						
		// "#  @   ##" 																						
		// "#  #$$ ##" 																						
		// "#  #. .##" 																						
		// "#########"
		
		int k = -1; //Counts characters in Level Base.
		for (int i=0; i<grid.length; i++)
		{
			for (int j=0; j<grid[i].length; j++)
			{
			k=k+1;	
			grid[i][j] = Levelbase.charAt(k);
			
			if (j == 8) //Prints out the level.
			{
				println(grid[i][j]);
			}
			
				else
				{
					print(grid[i][j]);
				}
			}
	     }
		xpos = 3; // Set x of main char;
		ypos = 3; // Set y of main char;
        
        while (true); // Wait for the key on the other thread
	  }
	
	public void run ()
	{
        Thread t = new Thread() {
            public void run() {
                Keyboard kb = new Keyboard();
                kd.addListener(new KeyboardListener() {
                    public void keyPressed(boolean keydown, int vk) {
                        if (keydown && vk == Keyboard.VK_ESCAPE) {
                            print("aaa...");
                        }
                    }
                });
            }
        };
        t.start();
		createlevel();
	}
}
 

Nenad

~Choco Coronet~ Omnomnom
Reaction score
137
Yey! It works!

Can you just tell me whats with the Thread t = new Thread() and the repeated public void run(). i.e why are they there? ^^

Edit: Nevermind, i got it xD
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Hey, I have checked from what ConsoleProgram extends and it extends Program which extends JApplet. Basicly, you could have used addKeyListener, I didn't acm used it's own console at this time (I thought it was just a wrapper class).

Might be too late now tho.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top