Настройка System.in для чтения из JTextField

Я ищу направление о том, как заменить System.in с InputStream который читает прямо из JTextField,

До сих пор мой подход был в значительной степени методом проб и ошибок. У меня сейчас есть;

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;
  }
});

Это дает NoSuchElementException как в попытках чтения, когда ввод пуст, и я предполагаю, что никогда не может найти разделитель.

Какой подход мне не хватает?

2 ответа

Решение

Ну, это метод, который я использовал, чтобы заставить его работать правильно. Если кто-то может улучшить этот ответ, не стесняйтесь.

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;           
  }
}));

Вы смотрите на полпути, но:

Из Javadocs

Этот метод блокируется до тех пор, пока не будут доступны входные данные, не будет обнаружен конец потока или сгенерировано исключение.

http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InputStream.html

Таким образом, ваш метод должен просто ждать нажатия клавиши. Либо путем обработки NoSuchElementException, либо KeyListener, который проверяет, сколько (новых?) Символов доступно.

Семантика этого InputStream отличается от консольной, поэтому вам нужно принять некоторые конструктивные решения о том, как обрабатывать изменения, а не только нажатия клавиш.

Другие вопросы по тегам