...
> I'm learning j2se and i'm trying to write a
> simple console programm ....
Are you referring to the command line? Note that Java
is not a language well suited to interacting with the
command line, though a few more methods were added
in 1.5 (mostly for parsing input and output).
Andrew T.
berner2 - 07 Jul 2006 16:07 GMT
> ...
>> I'm learning j2se and i'm trying to write a
[quoted text clipped - 6 lines]
>
> Andrew T.
yes - the command line.
I think I'm gonna give up this one...
thanks anyway
> i want the user to have 5 seconds to answer the question,
> after 5 seconds system says ::bzzzzzzzzz time up :::::::
> and next question starts ....
> but i have a problem that I can't do anything
> when system is waiting for user input
> BufferedReader br ... ;
> br.readLine();
This should be pretty simple:
Thread.sleep(5000);
if( System.in.available() > 0 ) {
// User entered some data, read and handle it
} else {
// Not
}
Note, of course, that the user will be waiting for 5 seconds whether
or not anything is entered, but that may be good enough for your
purposes.
(Disclaimer: I don't pretend to understand all the complexities that
you're likely to encounter by doing this, but it hopefully will be
something for you to explore.)

Signature
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Chris Uppal - 08 Jul 2006 11:32 GMT
> Thread.sleep(5000);
> if( System.in.available() > 0 ) {
> // User entered some data, read and handle it
> } else {
> // Not
> }
Never use available().
That won't work (besides the problem you have already pointed out).
Available() will only answer how many bytes can be read without blocking (or,
more accurately, an unreliable and pessimistic estimate of how many bytes --
InputStream itself, for instance, is documented always to return 0). All it
can do is check its own buffers to see how much data is in them. That's
checking /its own/ buffers, not the OS's. In Unix whatever the user has typed
will still be in the TTY driver's buffers in the kernel, Java won't know
anything about it until it issues a read() -- at which time it will block
unless the user has already entered <carriage return> or <eof>. Roughly the
same is true on Windows.
Never use available().
-- chris
P.S. I don't think there is any way to do this which doesn't involve either
executing an external program or using JNI.
Rogan Dawes - 12 Jul 2006 13:59 GMT
>> Thread.sleep(5000);
>> if( System.in.available() > 0 ) {
[quoted text clipped - 23 lines]
> P.S. I don't think there is any way to do this which doesn't involve either
> executing an external program or using JNI.
As you mentioned in another thread, there IS a solution to this, using a
thread dedicated to reading from System.in:
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
public class ConsoleReader extends Thread {
private List<String> lines = new LinkedList<String>();
private BufferedReader reader;
public ConsoleReader(InputStream is) {
setDaemon(true);
reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
String line;
try {
while ((line = reader.readLine()) != null) {
synchronized(lines) {
lines.add(line);
lines.notifyAll();
}
}
} catch (IOException ioe) {
}
}
public String readLine(long timeout) {
synchronized(lines) {
lines.clear();
try {
lines.wait(timeout);
if (lines.size()>0)
return lines.get(0);
return null;
} catch (InterruptedException ie) {
return null;
}
}
}
public static void main(String[] args) {
ConsoleReader reader = new ConsoleReader(System.in);
reader.start();
System.out.println("Enter a line: ");
String line = reader.readLine(5000);
if (line == null) {
System.out.println("Timeout!");
} else {
System.out.println("You entered : '" + line + "'");
}
}
}
> I came up with an idea to do this in 2 threads
> timer, and question .. something like that ...
> is it the way ? ... but still it would hang on
> readLine() i think ....
I don't see a way to do it without threads. What about the following one?
Cheers,
Simon
import java.io.*;
public class ReadConsole {
private String input;
private void inputArrived(String input) {
// overwriting old value
// could also append it instead
this.input = input;
this.notify();
}
public void waitForInput() {
System.out.println("Question: What is 6x7?");
Thread inputThread = new Thread() {
public void run() {
try {
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
String line = console.readLine();
synchronized (ReadConsole.this) {
inputArrived(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
inputThread.setDaemon(true);
inputThread.start();
try {
synchronized (this) {
wait(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (input == null) {
System.out.println("::bzzzzzzzzz time up :::::::");
} else {
System.out.println("Your answer: '" + input + "'");
}
}
public static void main(String[] argv) throws Exception {
new ReadConsole().waitForInput();
}
}