问题
I'm looking for direction on how to replace System.in
with an InputStream
that reads directly from a JTextField
.
So far my approach has pretty much been trial and error. I currently have;
JTextField input = new JTextField();
System.setIn(new InputStream() {
int ptr = 0;
@Override
public int read() throws IOException {
int c;
try {
c = input.getText().charAt(ptr);
}
catch (IndexOutOfBoundsException ioob) {
return 0;
}
ptr++;
return c;
}
});
This yields an NoSuchElementException
as in attempts to read when the input is empty and I assume can never find a delimiter.
What approach am I missing?
回答1:
Well, this is the method that I used to get it working correctly. If anyone can improve this answer then feel free.
final LinkedBlockingQueue<Character> sb = new LinkedBlockingQueue<Character>();
final JTextField t = new JTextField();
t.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
sb.offer(e.getKeyChar());
}
...
});
System.setIn(new BufferedInputStream(new InputStream() {
@Override
public int read() throws IOException {
int c = -1;
try {
c = sb.take();
} catch(InterruptedException ie) {
}
return c;
}
}));
回答2:
You look halfway there, but:
From the Javadocs
This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.
http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InputStream.html#read%28%29
So your method should just wait for a key to be pressed. Either by handling NoSuchElementException, or a KeyListener that checks how many (new?) characters are available.
The semantics of this InputStream is different from a console one, so you need to make some design decisions on how to handle edits, not just keypresses.
来源:https://stackoverflow.com/questions/10951116/setting-system-in-to-read-from-jtextfield