Я недавно попробовал то же самое, вот мой код:
class TexfFieldStreamer extends InputStream implements ActionListener {
private JTextField tf;
private String str = null;
private int pos = 0;
public TexfFieldStreamer(JTextField jtf) {
tf = jtf;
}
//gets triggered everytime that "Enter" is pressed on the textfield
@Override
public void actionPerformed(ActionEvent e) {
str = tf.getText() + "\n";
pos = 0;
tf.setText("");
synchronized (this) {
//maybe this should only notify() as multiple threads may
//be waiting for input and they would now race for input
this.notifyAll();
}
}
@Override
public int read() {
//test if the available input has reached its end
//and the EOS should be returned
if(str != null && pos == str.length()){
str =null;
//this is supposed to return -1 on "end of stream"
//but I'm having a hard time locating the constant
return java.io.StreamTokenizer.TT_EOF;
}
//no input available, block until more is available because that's
//the behavior specified in the Javadocs
while (str == null || pos >= str.length()) {
try {
//according to the docs read() should block until new input is available
synchronized (this) {
this.wait();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
//read an additional character, return it and increment the index
return str.charAt(pos++);
}
}
и используйте его так:
JTextField tf = new JTextField();
TextFieldStreamer ts = new TextFieldStreamer(tf);
//maybe this next line should be done in the TextFieldStreamer ctor
//but that would cause a "leak a this from the ctor" warning
tf.addActionListener(ts);
System.setIn(ts);
Прошло много времени с тех пор, как я закодировал Java, так что я, возможно, не в курсе паттернов. Вероятно, вам также следует перегрузить int available()
, но мой пример состоит только из минимума, чтобы заставить его работать с BufferedReader
s readLine()
функцией.
Редактировать: Чтобы это работало для JTextField
, вы должны использовать implements KeyListener
вместо implements ActionListener
, а затем использовать addKeyListener(...)
в вашей TextArea. Нужная вам функция вместо actionPerformed(...)
- это public void keyPressed(KeyEvent e)
, и затем вам нужно проверить на if (e.getKeyCode() == e.VK_ENTER)
, и вместо использования всего текста вы просто используете подстроку из последней строки перед курсором с
//ignores the special case of an empty line
//so a test for \n before the Caret or the Caret still being at 0 is necessary
int endpos = tf.getCaret().getMark();
int startpos = tf.getText().substring(0, endpos-1).lastIndexOf('\n')+1;
для входной строки. Потому что в противном случае вы будете читать всю TextArea каждый раз, когда нажимаете ввод.