2

私のプログラムは、単純なGUIとスレッドを拡張するクラスで構成されています。

SwingUtilities.invokeLater()を使用してGUIのテキストフィールドを更新する方法を学習しようとしていますが、静的にせずにGUIのテキストフィールドに到達するにはどうすればよいですか?そして、私は正しい方向に進んでいますか、それともこれまでに何か間違ったことをしましたか:)?

コード

これは、スレッドを拡張するクライアントと呼ばれるクラスから取得されました。これは、SwingUtilities.invokeLater(Runnable)を使用してGUIを更新する場所です。

public void run(){
    while (socket.isConnected()) {

    if (input.hasNext()) {

        updateTextField();
    }

}
}

private void updateTextField() {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
  // here i want to update my textfield using txt.setText(input.nextLine());

        }
    });

}

UPDATE(これはこれまでの私のコードです)nullpointerexecptionを取得します

public void run(){
    while (socket.isConnected()) {
            String x = input.next();
            System.out.println(x);
    mg.updateChat(x); // this is the line that gives me the nullexeption

    }
}

私のGUIで

public void updateChat(final String input){
SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
    txtChat.setText(input); 
    }
}); 
}
4

4 に答える 4

2

への呼び出しを含むメソッドに final ローカル変数を設定することで、これを行うことができますinvokeLater()。実行可能なオブジェクト内からその変数にアクセスできます。

例えば:

public void run(){
  while (socket.isConnected()) {
    if (input.hasNext()) {
      String nextInput = input.next();
      myGui.updateTextField(nextInput);
    }
  }
}

あなたのGUIクラスで:

public void updateTextField(final String nextInput) {
  SwingUtilities.invokeLater(
    new Runnable(){
      @Override
      public void run() {
        // assuming a private JTextField variable, myTextField
        myTextField.setText(nextInput);
      }
    }
  );
}
于 2012-10-19T13:27:36.487 に答える
1

テキストフィールドは、クラスでインスタンス変数として宣言するかClient、別のクラスで宣言する場合は、Clientクラスからアクセスできる必要があります。

の使用については正しい方向に進んでいます。内部のメソッドSwingUtilities.invokeLater()内のテキストフィールドを更新するだけです。run()RunnableinvokeLater

于 2012-10-19T13:26:39.053 に答える
1

あなたのNPEについて:

public void run() {
  while (socket.isConnected()) {
    String x = input.next();
    System.out.println(x);
    mg.updateChat(x); // this is the line that gives me the nullexeption
  }
}

これはmgnull でなければならないことを意味します。その理由は、この変数に GUI への有効な参照を与えていないためです。これを解決するには、メソッドまたはコンストラクタ パラメータのいずれかを介して、表示された GUI への参照を渡す必要があります。たとえば、コンストラクター経由の場合、次のことができます。

public class MySocketConnector implements Runnable {
  private MainGui mg;

  public MySocketConnector(MainGui mg) {
    this.mg = mg;
  }

  @Override
  public void run() {
    while (socket.isConnected() {
      // ... etc...
    }
  }

  //...
}

編集 1
あなたのコメントについて:

mg を現在の GUI に変更するにはどうすればよいですか? 私は現在、次のコードでそれをインティライズしています: private MainGui mg;

これは変数を宣言するだけで、初期化はしません。

于 2012-10-19T14:52:16.213 に答える
0

できることの1つはString、クラスを拡張するフィールドをクラスに含めることThreadです。そして、run()メソッド内で、そのフィールドをテキストフィールドに必要な値に設定します。次に、内部で設定した文字列を返すメソッドを記述し、run()そのメソッドを呼び出してテキストフィールドを設定します。

于 2012-10-19T13:26:49.770 に答える