2012-02-11 3 views
1

私はSwingとApache Commonsを使用してターミナルアプリケーションを作っています。 System.outSystem.errJTextAreaに簡単にリダイレクトできましたが、どうすればSystem.inのようにできますか? Inputstreamメソッドをオーバーライドする必要がありますか? StringJTextAreaからバイト配列に変換してからInputStreamに渡す必要がありますか?コード例は素晴らしいでしょう。スイングコンポーネントにSystem.inをリダイレクト

答えて

4

私は最近、同じことを試してみました、ここに私のコードは次のとおりです。

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()もオーバーロードする必要がありますが、私の例は、BufferedReaderreadLine()の機能で動作させるための最小限のもので構成されています。

編集:これはあなたがimplements KeyListener代わりのimplements ActionListenerを使用して、あなたのTextAreaにaddKeyListener(...)を使用する必要がJTextFieldのために機能するために。あなたは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; 

でカーソルの前の最後の行からのサブストリングを使用し、全体のテキストを使用して。それ以外の場合は、Enterキーを押すたびにTextArea全体を読み取るためです。

+0

Cool Illは、JTextAreaの最後の行を取るように変更する必要があります。ありがとうございました – Giannis

+0

@latusakiうまくいけば、 'JTextArea'は' ActionEvent's afaikを生成しないので、少し修正する必要はありません。無関係なボタンを作成してそれにアクションリスナーを追加するか、 'JTextArea'をオーバーライドして' Ctrl-Enter'やそれに類するものを探すためにキーイベントをキャッチして、 'ActionEvent'を自分でトリガーすることができます。 – PeterT

+0

テキストフィールドでのテスト中に、何らかの理由でreadメソッドが呼び出されていません。 – Giannis

1

InputStreamのインプリメンテーションを作成する必要があります。スイングコンポーネントから入力を受け取ります。基本的にSwingコンポーネントからテキストをコピーして、InputStream入力が利用できない場合はコースをブロックする必要があります)。

関連する問題