5

私のメインアプリケーションクラスには、JTextArea(たとえばtxtArea)のオブジェクトがあります。main_applicationプログラムで別の2つのスレッドを作成しました。私が作成した2つのスレッドは、シリアルポートでの読み取りと書き込み用です。次に、シリアルポートの読み取りバッファデータをJTextAreaオブジェクトに配置します。したがって、main_applicationで作成されたJTextAreaオブジェクトをread-threadに渡して、read-threadが読み取り出力をJTextAreaに送信できるようにする必要があります。

しかし、このようにした後、私はnullポインタアクセスの問題に直面しています。main_applicationのJTextAreaオブジェクトをチェックすると、nullではありませんが、スレッドに渡した後、nullをチェックしました。私はそれがどのように起こるのかわかりません....オタクが私を助けることができれば私は幸せになります....

ありがとう、Surjya

4

4 に答える 4

2

別の回答で述べたように、swing スレッド自体の Swing コンポーネントの内容のみを変更できます。他のすべてのスレッドがこれを行うようにするための良い方法は、実際の JTextArea を公開するのではなく、main_application からテキスト領域にテキストを追加するための安全な方法を他のオブジェクトに提供することです。

public class main_application {

private JTextArea txtArea;

public void addText(final String txt) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            txtArea.setText(txtArea.getText() + txt);
        }
    });
}

}

これは単純な例ですが、必要に応じてこれを拡張できます。これは、2 つの不変文字列を追加するため、テキストに追加するよりコストのかかる方法も使用します。JTextArea.getDocument() を使用してモデルを取得し、ドキュメント内のミューテーション メソッドを使用して、テキストをより効率的に更新できます。ただし、このようなメソッドを提供することで、他のスレッドやオブジェクトに影響を与えることなく、将来的に実装を変更できます。

パラメータtxtは final であり、匿名の内部クラスで直接参照できるようにするために必要であることに注意してください。

これをメイン アプリケーション クラスから分離し、テキスト領域を操作するメソッド/ウェイのインターフェイスまたはクラスを他のスレッドから作成してから、このテキスト領域をラップするオブジェクトをそれらに渡すことができます。 .

于 2009-11-26T23:43:14.870 に答える
1

スレッド間でオブジェクトを共有すると、非常に面倒になる可能性があります。別のアプローチのアクターモデルについて読むことをお勧めします。特にGUIの分野では、Model-View-Controllerアプローチコードが役立ちます。

しかし、質問に戻ると、JTextAreaを静的変数にし、すべての異なるスレッドに静的インスタンスを自由に変更させることで、すぐにハックすることができます。

public static JTextArea TXTAREA

void main_application(){
    //set up app
    ...
    TXTAREA = new JTextArea()
    ...
}

次に、シリアル読み取りスレッドで、のテキストを設定しますTXTAREA。このソリューションは理想的ではありません。より良いアプローチは、MVCアプローチを使用し、テキスト領域に配置する値を受け入れるコントローラーを使用することだと思います。

于 2009-11-25T04:01:43.930 に答える
0

SynchronousQueue を見てください。

http://java.sun.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html

オブジェクトをキューに保存し、削除されるまで待機することができます。

于 2009-11-25T04:29:58.667 に答える
0
  1. Swing コンポーネントは MVC ベース (実際には model-ui) であるため、JTextArea 参照を別のスレッドに公開することは正しくありません。したがって、swing コンポーネントを操作する一般的な方法は、モデルを更新し、ビュー (ui) に変更を表示させることです。
  2. もう 1 つのポイントは、swing コンポーネントのほとんどはスレッドセーフではないということです。つまり、swing コンポーネントをEDTよりもスレッドから使​​用すると、アプリケーションが正常に動作するかどうかを確認できません。

そのため、次のことを行う必要があります。新しいデータを表示するたびに、EDT から実行されるJTextAreaコンテンツ更新の新しいタスクを送信します。SwingUtilities.invokeLater()を介してそれを実現できます

于 2009-11-25T05:35:57.983 に答える