Jump to content

I'm doing a little java project just for the fun of it and I'm stuck trying to think of a 'click to continue' segment of code. I tried using the Keyboard class with no luck and so far, I am using a Scanner to read nextLine(). I have the output telling the user to press enter to continue, but I would like the user to have the ability to press any key.

Any help would be appreciated. Thanks!

Link to comment
https://linustechtips.com/topic/5087-java-help/
Share on other sites

Link to post
Share on other sites

I would set the scanner's index to the last line, then when something else has been input, check it and make sure it wasn't the same as the line before it. I've personally never used the Scanner to get keyboard input from the console, so this solution might not work. My guess is that you're a beginner, so if you haven't heard of Oracle's JavaDoc, it can be quite useful. http://docs.oracle.com/javase/7/docs/

Hope this helps :D

Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-59315
Share on other sites

Link to post
Share on other sites

It is possible but it is difficult to understand. By default java needs an escape sequence to stop the scanning of characters entered through the keyboard. So none of the Java Docs are going to be useful. What you need is some knowledge of C.

In the following code I am going to use the concept of Java Native Interface (JNI) to solve your problem. JNI helps java to call and run native functions coded in native languages like C and C++. Sadly I know how to do this on a Linux/Mac machine. I have no idea on how to do it on a Windows machine but the tut will give you a some idea on how to do it in Windows. Try MinGW for Windows. MinGW will provide you the GCC to compile the following C code.

Firstly, since I am using linux I need to create my own library which will have a function. That function will accept only one character and return some value. People call that function kbhit()

Descrpiton of kbhit:

kbhit returns the value 1 if a character is present in the keyboard buffer. kbhit returns a nonzero value if the user has pressed a key or the value zero if he or she has not. kbhit does not return the character associated with the key.

So lets get started.

Here's the java code that you'll need.

NativeKeybHandler.java:

public class NativeKeybHandler{    private native int kbhit();
    public static void main(String args[])    {
    }}

As you see I have declared a function called kbhit(), which is a native function.

Compile the file using the following command:

javac NativeKeybHandler.java

To create this native function we need to produce a native C header file. The JDK provides a header file generator called "javah" which is located in the bin folder of the JDK home. So if your PATH variable is set correctly, you should be able to run the following command and generate a header file "NativeKeybHandler.h" .

javah -jni NativeKeybHandler

Now lets create a file called "libNativeKeyb.c" and copy the following code in it:

#include #include #include #include #include "NativeKeybHandler.h"
JNIEXPORT jint JNICALL Java_NativeKeybHandler_kbhit(JNIEnv * env, jobject obj){  struct termios oldt, newt;  int ch;  int oldf;
  tcgetattr(STDIN_FILENO, &oldt);  newt = oldt;  newt.c_lflag &= ~(ICANON | ECHO);  tcsetattr(STDIN_FILENO, TCSANOW, &newt);  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
  ch = getchar();
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  fcntl(STDIN_FILENO, F_SETFL, oldf);
  if(ch != EOF)  {    ungetc(ch, stdin);    return 1;  }
  return 0;}

Yes I know I have shamelessly copied and modified someone else's code.

Compile it using the following command:

 gcc -fPIC -m32 -shared -o libNativeKeyb.so -I/usr/java/jdk1.7.0_10/include/ -I/usr/java/jdk1.7.0_10/include/linux/ libNativeKeyb.c 

NOTE: You may have to change the paths in the above command according to the location of the jdk. If you are using MinGW in Windows, don't forget to change "linux" to "win32" and "libNativeKeyb.so" to "libNativeKeyb.dll" in the above command.

So now the files you have are:

1) NativeKeybHandler.java, NativeKeybHandler.class

2) NativeKeybHandler.h

3) libNativeKeyb.c, libNativeKeyb.so

The file libNativeKeyb.so is a native dynamic library which is to be linked to you java program. The following code should be self explanatory:

public class NativeKeybHandler{    /* Loading the library */    static {        System.load("/root/Desktop/keyb/libNativeKeyb.so");    }
    private native int kbhit();
    public static void main(String args[])    {        NativeKeybHandler NKH = new NativeKeybHandler();
        while(NKH.kbhit() == 0)        {            /* This will loop on till you press a key */        }
    }}

There you have it. You can modifiy the above program to suit you needs.

To learn more about JNI, go here: http://docs.oracle.com/javase/7/docs...es/guides/jni/

Hope this helps :)

Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-62548
Share on other sites

Link to post
Share on other sites

It is possible but it is difficult to understand. By default java needs an escape sequence to stop the scanning of characters entered through the keyboard. So none of the Java Docs are going to be useful. What you need is some knowledge of C.

In the following code I am going to use the concept of Java Native Interface (JNI) to solve your problem. JNI helps java to call and run native functions coded in native languages like C and C++. Sadly I know how to do this on a Linux/Mac machine. I have no idea on how to do it on a Windows machine but the tut will give you a some idea on how to do it in Windows. Try MinGW for Windows. MinGW will provide you the GCC to compile the following C code.

Firstly, since I am using linux I need to create my own library which will have a function. That function will accept only one character and return some value. People call that function kbhit()

Descrpiton of kbhit:

kbhit returns the value 1 if a character is present in the keyboard buffer. kbhit returns a nonzero value if the user has pressed a key or the value zero if he or she has not. kbhit does not return the character associated with the key.

So lets get started.

Here's the java code that you'll need.

NativeKeybHandler.java:


public class NativeKeybHandler

{

private native int kbhit();

public static void main(String args[])

{

}

}

As you see I have declared a function called kbhit(), which is a native function.

Compile the file using the following command:

javac NativeKeybHandler.java

To create this native function we need to produce a native C header file. The JDK provides a header file generator called "javah" which is located in the bin folder of the JDK home. So if your PATH variable is set correctly, you should be able to run the following command and generate a header file "NativeKeybHandler.h" .

javah -jni NativeKeybHandler

Now lets create a file called "libNativeKeyb.c" and copy the following code in it:


#include

#include

#include

#include

#include "NativeKeybHandler.h"

JNIEXPORT jint JNICALL Java_NativeKeybHandler_kbhit(JNIEnv * env, jobject obj)

{

struct termios oldt, newt;

int ch;

int oldf;

tcgetattr(STDIN_FILENO, &oldt);

newt = oldt;

newt.c_lflag &= ~(ICANON | ECHO);

tcsetattr(STDIN_FILENO, TCSANOW, &newt);

oldf = fcntl(STDIN_FILENO, F_GETFL, 0);

fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)

{

ungetc(ch, stdin);

return 1;

}

return 0;

}

Yes I know I have shamelessly copied and modified someone else's code.

Compile it using the following command:

 gcc -fPIC -m32 -shared -o libNativeKeyb.so -I/usr/java/jdk1.7.0_10/include/ -I/usr/java/jdk1.7.0_10/include/linux/ libNativeKeyb.c 

NOTE: You may have to change the paths in the above command according to the location of the jdk. If you are using MinGW in Windows, don't forget to change "linux" to "win32" and "libNativeKeyb.so" to "libNativeKeyb.dll" in the above command.

So now the files you have are:

1) NativeKeybHandler.java, NativeKeybHandler.class

2) NativeKeybHandler.h

3) libNativeKeyb.c, libNativeKeyb.so

The file libNativeKeyb.so is a native dynamic library which is to be linked to you java program. The following code should be self explanatory:


public class NativeKeybHandler

{

/* Loading the library */

static {

System.load("/root/Desktop/keyb/libNativeKeyb.so");

}

private native int kbhit();

public static void main(String args[])

{

NativeKeybHandler NKH = new NativeKeybHandler();

while(NKH.kbhit() == 0)

{

/* This will loop on till you press a key */

}

}

}

There you have it. You can modifiy the above program to suit you needs.

To learn more about JNI, go here: http://docs.oracle.com/javase/7/docs...es/guides/jni/

Hope this helps :)

WOW! This is so much more help than I expected to receive. Thank you thank you thank you!!!!!

Although it's going to take a few moments to digest the whole JNI thing, I understood the general concepts you have outlined. Again, thank you for your help.

Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-63993
Share on other sites

Link to post
Share on other sites

It is possible but it is difficult to understand. By default java needs an escape sequence to stop the scanning of characters entered through the keyboard. So none of the Java Docs are going to be useful. What you need is some knowledge of C.

In the following code I am going to use the concept of Java Native Interface (JNI) to solve your problem. JNI helps java to call and run native functions coded in native languages like C and C++. Sadly I know how to do this on a Linux/Mac machine. I have no idea on how to do it on a Windows machine but the tut will give you a some idea on how to do it in Windows. Try MinGW for Windows. MinGW will provide you the GCC to compile the following C code.

Firstly, since I am using linux I need to create my own library which will have a function. That function will accept only one character and return some value. People call that function kbhit()

Descrpiton of kbhit:

kbhit returns the value 1 if a character is present in the keyboard buffer. kbhit returns a nonzero value if the user has pressed a key or the value zero if he or she has not. kbhit does not return the character associated with the key.

So lets get started.

Here's the java code that you'll need.

NativeKeybHandler.java:


public class NativeKeybHandler

{

private native int kbhit();

public static void main(String args[])

{

}

}

As you see I have declared a function called kbhit(), which is a native function.

Compile the file using the following command:

javac NativeKeybHandler.java

To create this native function we need to produce a native C header file. The JDK provides a header file generator called "javah" which is located in the bin folder of the JDK home. So if your PATH variable is set correctly, you should be able to run the following command and generate a header file "NativeKeybHandler.h" .

javah -jni NativeKeybHandler

Now lets create a file called "libNativeKeyb.c" and copy the following code in it:


#include

#include

#include

#include

#include "NativeKeybHandler.h"

JNIEXPORT jint JNICALL Java_NativeKeybHandler_kbhit(JNIEnv * env, jobject obj)

{

struct termios oldt, newt;

int ch;

int oldf;

tcgetattr(STDIN_FILENO, &oldt);

newt = oldt;

newt.c_lflag &= ~(ICANON | ECHO);

tcsetattr(STDIN_FILENO, TCSANOW, &newt);

oldf = fcntl(STDIN_FILENO, F_GETFL, 0);

fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)

{

ungetc(ch, stdin);

return 1;

}

return 0;

}

Yes I know I have shamelessly copied and modified someone else's code.

Compile it using the following command:

 gcc -fPIC -m32 -shared -o libNativeKeyb.so -I/usr/java/jdk1.7.0_10/include/ -I/usr/java/jdk1.7.0_10/include/linux/ libNativeKeyb.c 

NOTE: You may have to change the paths in the above command according to the location of the jdk. If you are using MinGW in Windows, don't forget to change "linux" to "win32" and "libNativeKeyb.so" to "libNativeKeyb.dll" in the above command.

So now the files you have are:

1) NativeKeybHandler.java, NativeKeybHandler.class

2) NativeKeybHandler.h

3) libNativeKeyb.c, libNativeKeyb.so

The file libNativeKeyb.so is a native dynamic library which is to be linked to you java program. The following code should be self explanatory:


public class NativeKeybHandler

{

/* Loading the library */

static {

System.load("/root/Desktop/keyb/libNativeKeyb.so");

}

private native int kbhit();

public static void main(String args[])

{

NativeKeybHandler NKH = new NativeKeybHandler();

while(NKH.kbhit() == 0)

{

/* This will loop on till you press a key */

}

}

}

There you have it. You can modifiy the above program to suit you needs.

To learn more about JNI, go here: http://docs.oracle.com/javase/7/docs...es/guides/jni/

Hope this helps :)

You're welcome :) If you need any more help, don't hesitate to drop by at the forums. I'll be happy to help you :)
Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-64868
Share on other sites

Link to post
Share on other sites

The solution presented above seems to work as expected, however complicated it may seem (and it seems quite complicated to me!; I have only tried to call a java method from C and not the other way around), but one very bad side effect will be high cpu usage: because of the loop you have on your java program the process will not yield while waiting for a key to be pressed like the stdIn.readLine() would if you used it.

So if you don't mind having that process use all the cpu time then this works, but if you have something else happening that needs the cpu you will (probably) notice some slowdown and then maybe it would be better if the user just pressed any button, as long as it is the enter!

Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-66275
Share on other sites

Link to post
Share on other sites

@MikeD: Ahh, nice observation. Yes my solution does use 100% of the CPU. My bad. :) But if you don't like the solution what you could do is study about Processes in Java. It helps you call native executable files. So the C code I gave you can be compiled into an executable and can be called from java instead of running it natively through the JVM. That may not use 100% of the CPU.

Try it out :)

Link to comment
https://linustechtips.com/topic/5087-java-help/#findComment-67977
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×