O metodo read() da classe InputStream é sincrono.
Tente usar esta classe que cuida disso pra vc.
Classe TrataTeclado
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package br.org.luca.event;
import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.EventListenerList;
/**
* Classe responsável em tratar as entradas do teclado e
* notificar as classes registradas.
* @author Luca Martins
*/
public class TrataTeclado extends Thread{
private BufferedInputStream in = null;
private static final Integer BUFFER_SIZE = 255;
private EventListenerList eventList = null;
private volatile boolean run = false;
private boolean reverse = false;
/**
* Construtor - Instancia e inicia esta Thread
*/
public TrataTeclado(){
eventList = new EventListenerList();
in = new BufferedInputStream(System.in);
start();
}
/**
* Registra a classe para ser notificada quando houver um comando
* @param l Classe a ser notificada
*/
public void addEventoTecladoListener( CommandListener l ){
eventList.add(CommandListener.class, l);
}
/**
* Desregistra a classe da lista de eventos
* @param l Classe a ser removida
*/
public void removeEventoTecladoListener( CommandListener l ){
eventList.remove(CommandListener.class, l);
}
/**
* {@inheritDoc}
*/
@Override
public void start(){
run = true;
super.start();
}
/**
* Dispara os eventos para as classes registradas
* @param toString Comando que será enviado para as classes
*/
private void fireTecladoEvent(String toString) {
CommandListener listeners[] = eventList.getListeners( CommandListener.class );
EventoTeclado evt = new EventoTeclado(this, 1);
String str[] = parse(toString);
evt.setCommand(str[0]);
evt.setParam(str[1]);
for( CommandListener listener : listeners ){
listener.commandReceived(evt);
}
}
/**
* Instrui se o comando recebido da entrada deve ser
* revertido antes de notificar as classes do evento.
* <br><br><font size=3 color='red'>Atenção! Este metodo foi criado
* para corrigir um bug no netbeans 6.0, que em determinados momentos recebe
* o input de forma invertida.</font>
* @param reverse Se a string deve ser invertida {@code Boolean.TRUE}
* caso contrario {@code Boolean.FALSE}
*/
public void setReverseOn( boolean reverse ){
this.reverse = reverse;
}
/**
* Metodo que faz a execução dessa Thread finalizar
*/
public void paraTudo(){
run = false;
}
private String[] parse( String cmd ){
String ret[] = new String[2];
Integer index = cmd.indexOf(" ");
if( index <= 0 ){
ret[ 0 ] = cmd;
}else{
ret[ 0 ] = cmd.substring(0, index);
ret[ 1 ] = cmd.substring(index);
}
return ret;
}
/**
* Consome a entrada do teclado
*/
public void run(){
byte buffer[] = new byte[ BUFFER_SIZE + 1 ];
int read = -1;
StringBuffer strb = new StringBuffer();
while(run){
try {
//Aguarda existir algo na entrada
while (in.available() <= 0) {
Thread.sleep(100);
}
while( in.available() > 0 ){
read = in.read(buffer);
strb.append( new String( buffer, "UTF-8").trim() );
Arrays.fill(buffer, (byte)0);
}
/*fireTecladoEvent( strb.reverse().toString() );*/
fireTecladoEvent( reverse ? strb.reverse().toString() : strb.toString() );
strb.delete(0, strb.length() );
Thread.sleep(10);
} catch (Exception ex) {
Logger.getLogger(TrataTeclado.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Classe EventoTeclado
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package br.org.luca.event;
import java.awt.AWTEvent;
import java.awt.Event;
/**
*
* @author Luis.Leao
*/
public class EventoTeclado extends AWTEvent{
private String cmd, param;
public String getParam() {
return param;
}
protected void setParam(String param) {
this.param = param;
}
protected EventoTeclado( Event ev ){
super(ev);
// eventList = new EventListenerList();
}
protected EventoTeclado( Object src, int id ){
super(src, id);
// eventList = new EventListenerList();
}
protected void setCommand( String cmd ){
this.cmd = cmd;
}
public String getCommand(){
return cmd;
}
}
Interface CommandListener
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package br.org.luca.event;
import java.util.EventListener;
/**
*
* @author Luis.Leao
*/
public interface CommandListener extends EventListener{
public void commandReceived(EventoTeclado evt);
}
Lembre-se ao finalizar sua aplicação chamar o metodo TrataTeclado.paraTudo().
Ela implementa o esquema de evento, então quando vc quiser que alguem receba o que foi digitado na entrada vc deve adicionar ao listener da classe TrataTeclado.
Qualquer Duvida estamos aqui!