Possible continuous console checking

E

eddieroger

Hello,

I am new to Java but quickly getting my bearing, and I'm looking for a
way to continuously check the console's input without the user needing
to press "enter". I'm working on a little project where users can enter
numbers on a keypad, and selections will be made, but I'd like to avoid
using the enter or return keys to complete the line if possible. Is it
possible? I'm using Scanner for checking console input, and as of now,
I don't know any other ways, but I'm completely open to finding them. I
appreciate the help in advance. Thanks.

//eddieroger
 
C

Chris Smith

I am new to Java but quickly getting my bearing, and I'm looking for a
way to continuously check the console's input without the user needing
to press "enter".

There are third-party JNI-based libraries able to do this, and other
things that you'll want if you're trying to build a real interactive
user interface with Java's console. Google for "jcurses".
I'm using Scanner for checking console input, and as of now,
I don't know any other ways, but I'm completely open to finding them.

The only class called "Scanner" in the Java standard API is used to
parse text, and has nothing to do with console I/O. If your Scanner is
not part of the standard Java API, you'll have to tell use where you got
it before anyone can answer questions about what it can or cannot do.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jean-Francois Briere

The only class called "Scanner" in the Java standard API is used to
parse text, and has nothing to do with console I/O.

Maybe the OP meant that java.util.Scanner is used in conjunction with
System.in to help parse the standard input stream.
Just an assumption though.
 
E

eddieroger

Let me rephrase, as I didn't say what I meant to say. The scenario is
the program will just sit there and wait for a user to type in a key.
Which key it is doesn't matter, but the program takes it in. The
simplest thing it will do is return the string, like a really simple
echo. Specifically, however, it will wait for three numbers, and act
once it receives three, like a jukebox waiting for a song selection.
Once it realizes that three numbers were entered, it will take them and
go do whatever it needs to with them. It will probably be easier to
forget everything I mentioned in my first post and ask for direction in
this manner. Thanks for the quick replies and continued help.

//eddieroger
 
C

Chris Smith

It will probably be easier to
forget everything I mentioned in my first post and ask for direction in
this manner. Thanks for the quick replies and continued help.

Nope. Read my first reply. Your situation is the same, and my answer
is the same.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
A

Andrew Thompson

...I'm using Scanner for checking console input, and as of now,
I don't know any other ways, but I'm completely open to finding them.

Other ways to read the console, or other ways to get three numbers?

If the latter, I would recommend dumping the command line
completely, and writing a GUI for your users.
 
Z

zero

Other ways to read the console, or other ways to get three numbers?

If the latter, I would recommend dumping the command line
completely, and writing a GUI for your users.

Yep, a Component - any Component - with a keyListener attached to it can
solve your problem easily.

If you really want the console then maybe you can do something (rather
messy) with System.in.read() in a while loop.

int[3] rcvd; // array containing the read bytes
int count = 0; // number of bytes read
while(count < 3)
{
int read = System.in.read(); // read next byte on stream
if(read != -1) // if a byte was indeed read
rcvd[count++] = read; // inc count and store the byte
}
// ... handle the 3 read bytes

This is completely untested, off the top of my head, so it may be very
wrong. Don't sue me if it is.
 
I

iksrazal

(e-mail address removed) escreveu:
Let me rephrase, as I didn't say what I meant to say. The scenario is
the program will just sit there and wait for a user to type in a key.
Which key it is doesn't matter, but the program takes it in. The
simplest thing it will do is return the string, like a really simple
echo. Specifically, however, it will wait for three numbers, and act
once it receives three, like a jukebox waiting for a song selection.
Once it realizes that three numbers were entered, it will take them and
go do whatever it needs to with them. It will probably be easier to
forget everything I mentioned in my first post and ask for direction in
this manner. Thanks for the quick replies and continued help.

//eddieroger

What you seemingly want is the non ansi standard kbhit() from the c
language. This is a good reason why java should be open-sourced,
because there has been a 9 year bug report / feature request that was
long been ignored by sun:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4050435

Curiously, this finally may be somewhat fixed in java 6.

http://download.java.net/jdk6/docs/api/java/io/Console.html

Its beta, I'm reserving judgement. I don't have time at the moment to
dig into it.

In the meantime, see the comments in the bug report for work arounds as
well as an opensource library 'readline' .

http://java-readline.sf.net/

HTH,
iksrazal
http://www.braziloutsource.com/
 
R

robert.colquhoun

What you seemingly want is the non ansi standard kbhit() from the c
language. This is a good reason why java should be open-sourced,
because there has been a 9 year bug report / feature request that was
long been ignored by sun:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4050435

I voted for this more than 5 years ago...
Curiously, this finally may be somewhat fixed in java 6.
http://download.java.net/jdk6/docs/api/java/io/Console.html
Its beta, I'm reserving judgement. I don't have time at the moment to
dig into it.

The current beta only has methods for inputting a password, no single
character input. There is a Reader class attached to the Console
object(which in turn is available via a static System method). Sadly
the reader only does line buffered input.

Maybe a new feature request needs to opened with sun? .... based on
progress of last feature request single char input should be available
in 2015 or so....(that's got to be some kind of record to write only
100 lines or so of code).
In the meantime, see the comments in the bug report for work arounds as
well as an opensource library 'readline' .

Also jline (more platforms, no gnu-readline dependency and under bsd
license):
http://jline.sourceforge.net/

- Robert
 
T

Thomas Weidenfeller

I voted for this more than 5 years ago...

A kbhit() alone is nonsense in a multiuser/multitasking operating
system. Java lacks any decent console I/O support, but that can't be
fixed with just a kbhit() in a platform independent way. You have the
whole issue of line discipline at hand in many operating systems, the
fact that terminals use different control sequences and different modes
of operation, etc.

The Sun engineers apparently have an aversion against "legacy" systems
like text consoles. They recently even scratched the JavaComm (the
serial I/O API) reference implementation for Windows. I would not expect
to see anything text-only related feature from Sun at all.

What you can do is what people always have done: Get a JNI library, e.g.
some Java [n]curses wrapper.
Maybe a new feature request needs to opened with sun? .... based on
progress of last feature request single char input should be available
in 2015 or so....(that's got to be some kind of record to write only
100 lines or so of code).

Just single-char input will not cut it.

/Thomas
 
R

robert.colquhoun

Hello,
A kbhit() alone is nonsense in a multiuser/multitasking operating
system. Java lacks any decent console I/O support, but that can't be
fixed with just a kbhit() in a platform independent way. You have the
whole issue of line discipline at hand in many operating systems, the
fact that terminals use different control sequences and different modes
of operation, etc.

I dont understand, what else would be required apart from single
character console input? I thought everything else needed could be
built above the jvm level in a java library that would be pretty much
platform independent.

The line displine etc is handled by the jvm in order to get the
kbhit/getchar etc function enabled for the platform. The jvm is
abstracting that level, like it abstracts so much else from the
underlying operating system.

Can you find me a platform that has consoles and java is ported to,
that doesnt have single char input as a native function already?
The Sun engineers apparently have an aversion against "legacy" systems
like text consoles. They recently even scratched the JavaComm (the
serial I/O API) reference implementation for Windows. I would not expect
to see anything text-only related feature from Sun at all.

It's kindof ironic really, so many server type applications require a
text style interface to administer not to mention to integrate with
existing text oriented applications. ie unix admins seem to do
everything via scripts which are text oriented, web interfaces they
often find a real pain for repetitive tasks.

Difficulty in writing java server applications means less java server
applications which in turn means less demand for solaris, you would
think somebody would make the connection...
What you can do is what people always have done: Get a JNI library, e.g.
some Java [n]curses wrapper.

That's the point though the above is being repeated so many times, the
rfe was in the top 25, the top 10 i think, for 8+ years.

Your server application which previously was 100% portable, now becomes
platform dependent, taking away a major benefit of writing it in java.
Just single-char input will not cut it.

Can you please explain what else is needed.

- Robert
 
I

iksrazal

(e-mail address removed) escreveu:
Hello,



Can you please explain what else is needed.

- Robert

Think about how kbhit() in C is normally used, and shells in general,
and I think its safe to say that a multiuser shell environnment
stretches the imagination.

single-char input is a common enough requirement that should be solved,
period.

To be fair, kbhit() is highly useful in C - I used it alot - but it is
non standard. This C version wouldn't work on M$:

http://www.linuxjournal.com/articles/lj/0017/1138/1138l1.html

And no other language I know of - python. perl, for example - have an
OS independent kbhit like function portable accross *nix and M$.

More to the point, java's version of GNU readline, and jline, all use
JNI underneath.

Still, one wonders why threads and sockets can be portable, but a
simple character based escape loop cannot be. You can even manipulate
memory directly via sun.misc.unsafe. Unix signals are very platform
specific yet can be used via sun.misc.Signal. Why couldn't a -D flag
or System property or such be used indicating OS or a terminal like
vtm100? Its not as big of problem as with C, because java really only
supports 3 platforms.

It was about nine years ago I implemented C kbhit() the first time, and
nine years and waiting for the java bug report to be solved...

iksrazal
 
G

Gordon Beaton

It was about nine years ago I implemented C kbhit() the first time, and
nine years and waiting for the java bug report to be solved...

Turn off canonical mode in your shell (e.g. with stty) before starting
your java application, and you get character-a-time input on
System.in.

/gordon
 
T

Thomas Weidenfeller

I dont understand, what else would be required apart from single
character console input?

kbhit() polls the keyboard. This is a big no-no in a multiuser,
multitasking system. You are going to burn CPU cycles just to check if
there is a character pressed on the keyboard. Typical kbhit() code looks
like:

while(!kbhit())
; /* burn CPU cycles like there is no tomorrow */
getc(); /* finally get some character */

Also, you, or your application probably doesn't own the keyboard at the
time you run kbhit(). What should kbhit() do? Still tell you that a key
is pressed, even if you can't get it?

And, you typically can't poll remotely connected terminals if they have
a character ready. They either have send something or not, but there is
nothing to poll.

kbhit() has been left out of the C standard for very good reasons,
because not all IO systems follow a simple PC like architecture.

And to continue, there is more in a terminal driver than just delivering
characters unaltered. You need to get control over the driver and thus
over the terminal to successfully control character input. Controlling
buffering, handling/replacement of EOL and other characters, (escape)
encoded special keys, turning on or off parts of a keyboard (numeric
input field).

If you communicate with a real terminal, there is much fun involved.
Sometimes you want it one way, sometimes you want it to behave the other
way, and a generic "just look if a key has been hit" doesn't cut it.
The line displine etc is handled by the jvm in order to get the
kbhit/getchar etc function enabled for the platform. The jvm is
abstracting that level, like it abstracts so much else from the
underlying operating system.

And how do you know which particular setting of the driver a particular
application requires? If you stick with Unix termios, there are roughly
50+ configuration parameters. Some settings are more likely than others,
but there is a heap of stuff to go mad about.

Unix has a library on top of that, the very appropriately named
"curses". That one basically weaves together driver handling, and
terminal-specific configuration and control characters (using the
terminfo or older termcap database), and provides a slightly higher
level API (plus some stuff like fragments of a text-based windowing system).
Can you find me a platform that has consoles and java is ported to,
that doesnt have single char input as a native function already?

Define "native". If we again take Unix for example, then a kbhit() is
not there, and should not be there. You do not poll on such systems. To
get a single character you have to first configure the terminal driver.
You can either do that with a library (e.g. termios, which is basically
a driver interface or e.g. the "higher level" curses) from within your
application. Or one sometimes can get away with configuring the line on
the command line with a tool called stty.

And until now we only talked about terminal input. Output is equally
fun, since sometimes you have to take timing into account so not to
overrun a terminal's buffer or CPU. Different terminals use different
sequences to color or highlight text, sometimes in the most crazy ways
(I well remember old HP terminals for having a horrible way of handling
highlighting). Different terminals provide different numbers of lines
and columns, scroll buffers, etc.
Difficulty in writing java server applications means less java server
applications which in turn means less demand for solaris, you would
think somebody would make the connection...

The Sun Java folks and the Sun Solaris folks apparently don't get very
well along. There was a famous memory leak some time ago, where the
Solaris folks bitterly complained about the Java release management, bug
fix releases and how unsuitable Java was for their purpose.
That's the point though the above is being repeated so many times, the
rfe was in the top 25, the top 10 i think, for 8+ years.

Now you know why people don't take things like Sun's bug parade very
serious. Sun anyhow does what they want. They rather preferred to add a
skinnable L&F or generics or whatever to the language, than taking care
of these things.
Can you please explain what else is needed.

For a start what is in curses, like facilities to open and close a
terminal/console connection, to configure the driver in a suitable way,
to map escape sequences to standard key codes, to generate the control
sequences needed by a particular terminal, to drive the timing on the
line. To get information about the number of lines and columns, etc.

Java will give you an extra headache, since you have to know the
character code which comes from and goes to the terminal or console.
Everything inside Java is Unicode, but that's not what a terminal /
console will likely speak.

Curses is really not great, but a standardized curses version in Java
would be better than nothing. But expect Sun to implement yet another
LAF than doing something like this.

/Thomas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top