1

一部のデータを処理する GUI アプリケーションがあり、テキスト行をオブジェクトに変換します。作成された各オブジェクトは、JTextPane または JTextArea に表示されます。例:

行 # 1 が作成されました 827401830 行 # 2 が作成されました 827401831

したがって、ユーザーはプロセスを通知されます。

舞台裏では、バックグラウンドで実行され、すべての作業を行うスレッドがあります。問題は、このスレッドのフィールドの 1 つに JTextArea があることです。次のようになります。

public class ConsumerThread implements Runnable 
{
    private ArrayBlockingQueue<TicketExchangeLine> queue;
    private JTextArea textArea; 

public ExchConsumerThread(ArrayBlockingQueue<TicketExchangeLine> queue, JTextArea textArea) 
{
    this.queue = queue;
    this.textArea = textArea; 
}

public void run() 
{
    try
    {       
        while (true)
        {               
            // check if end of file from producer POV
            if (queue.peek()!=null && ...)
                break;

            MyObject obj = queue.take();

            try{
                //do the process here
                textArea.append("here comes the output for the user..."+obj.getID);

            }catch(Exception nfe)
            {
                //Oops  
            } 
        }

        textArea.append("\nDone!");

    }catch (InterruptedException e)
    {
        // Oops
    }catch(Exception exp)
    {
        exp.printStackTrace();
    }
}

}

したがって、上記のコードは正常に機能し、ジョブを実行しますが、GUI からではなくこのスレッドを使用していて、理由もなく JTextArea をインスタンス化していることがあります。さらに悪いことに、プロセスを確認するためにすべてを system.out する必要があります。

質問: スレッドで Swing コンポーネントを使用せずに、すべての「処理されたデータ」を JTextArea (または場合によっては JTextPane) に記録するにはどうすればよいですか?

ありがとう!

4

4 に答える 4

2

a を渡す代わりにJTextAreaOutputStream(たとえば a PrintStream) をパラメーターとして渡します。これにより、十分な柔軟性が得られます。

  • あなたのスレッドは出力ストリームに書き込むだけです
  • 出力を に表示する場合はJTextArea、出力を に追加する outputstream を渡しますJTextArea。テキスト領域への書き込みは EDT で行われる必要がありますが、出力ストリームがこれを処理します。あなたのスレッドはこれを認識していません
  • 出力を にパイプする場合は、 をパラメータとして直接System.out渡します。System.out
于 2012-05-04T13:40:19.590 に答える
1

ほとんどの Swing グラフィカル コンポーネントは、グラフィカルな表現 (ビュー) と表示されるデータの抽象的な表現 (モデル) に分割されます。インスタンスをモデルとしてJTextArea使用JTextPaneするグラフィカル コンポーネントです。Document

したがって、 を参照して を呼び出す代わりに、ドキュメントを参照してJTextAreaを呼び出すことができます。次に、JTextArea をインスタンス化する必要がある場合は、Document を引数として取る (またはそのメソッドを使用する) JTextArea のコンストラクターを使用します。textArea.appenddocument.insertStringsetDocument

また、Swing はスレッド セーフではなく、Swing コンポーネントに影響を与える可能性のあるすべてのメソッド呼び出しは、EDT (AWT のディスパッチ スレッド) で発生する必要があります。EDT にコードを挿入するには、 を使用しますSwingUtilities.invokeLater

于 2012-05-04T13:40:26.593 に答える
0

あなたはすでに答えを見つけているようですが、これはあなたの問題に対するエレガントで柔軟な解決策だと思います:

さまざまな場所から Swing JTextArea にメッセージを送信する

于 2012-09-11T07:54:56.747 に答える
0

それがあなたが達成しようとしているものかどうかはわかりませんが、現在のコードでは、EDTの JTextArea を次のように変更できます。

final MyObject obj = queue.take();
try {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            textArea.append("here comes the output for the user..." + obj.getID);
        }
    });
}
于 2012-05-04T13:31:12.960 に答える