2014-12-08 17 views
0

我有下面的代碼應該將System.in重定向到JTextField。但每當我嘗試new BufferedReader(new InputStreamReader(System.in)).readLine();時,Swing GUI都會掛起。我如何從System.in中讀取行而不掛上GUI線程?在System.in上的readLine不掛上Swing GUI線程

private static LinkedBlockingQueue<Character> sb = new LinkedBlockingQueue<Character>(); 
BufferedInputStream s = new BufferedInputStream(new InputStream() { 
    int c = -1; 

    @Override 
    public int read() throws IOException { 
     Thread thread = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        c = sb.take(); 
       } catch (InterruptedException ie) { 
        ie.printStackTrace(); 
       } 
      } 
     }); 
     thread.start(); 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return c; 
    } 
}); 
JTextField t = new JTextField(); 
    t.addKeyListener(new KeyListener() { 
     @Override 
     public void keyTyped(final KeyEvent e) { 
      sb.offer(e.getKeyChar()); 
      if (e.getKeyChar() == '\n' || e.getKeyChar() == '\r') { 
       t.setText(""); 
      } 
     } 

     @Override 
     public void keyPressed(KeyEvent arg0) { 
     } 

     @Override 
     public void keyReleased(KeyEvent arg0) { 
     } 
    }); 

System.setIn(s); 
+0

壞主意#1 - 't.addKeyListener(新的KeyListener()' – MadProgrammer 2014-12-08 04:55:00

+0

使用另一個線程有一個回調或?使用未來獲得結果嗎? – Jaskey 2014-12-08 04:57:00

+0

@Jaskey可以演示嗎?我需要第三方庫嗎? – 2014-12-08 04:59:39

回答

2

定義一個Callback類,在這裏我使用一個接口,可以跳過這個階段。

interface Callback { 
    void updateText(String s); 
} 

public class CallbackImpl implements Callback {// implements this interface so that the caller can call text.setText(s) to update the text field. 

    JTextField text;// This is the filed where you need to update on. 

    CallbackImpl(JTextField text){//we need to find a way for CallbackImpl to get access to the JTextFiled instance, say pass the instance in the constructor, this is a way. 
    this.text=text; 
    } 

    void updateText(String s){ 
     text.setText(s);//updated the text field, this will be call after getting the result from console. 
    } 
} 

定義執行作業的線程並在作業(從控制檯讀取)完成後調用回調方法。

class MyRunable implements Runnable { 

    Callback c; // need a callable instance to update the text filed 

    public MyRunable(Callback c) {// pass the callback when init your thread 
     this.c = c; 
    } 

    public void run() { 
     String s=// some work reading from System.in 
     this.c.updateText(s); // after everything is done, call the callback method to update the text to the JTextField. 
    } 

} 

要使其工作,你的聽衆,啓動這個線程:

new Thread(new MyRunable(new CallbackImpl(yourJtextFiled))).start();//start another thread to get the input from console and update it to the text field. 
+0

先生,我該如何實現this.c.callback(s)方法? – 2014-12-08 05:17:24

+0

text.setText(一個或多個);沒有EDT(對於Java7和更新版本), – mKorbel 2014-12-08 08:51:33

+0

@Jaskey是的,儘管我實際上只是將讀取移動到了System.in中。對不起,我以爲我已經在上面標記了答案。謝啦 – 2014-12-09 04:02:16