5

私は次のようなコードを持っています:

class SimplifiedClass extends JApplet {

    private JTextArea outputText;
    // Lots of methods
    public void DoEverything() {
        String output = "";
        for(int i = 0; i <= 10; i++) {
            output += TaskObject.someLongTask(i);
            outputText.setText(output);
        }
    }
}

ただし、setTextが呼び出されたときにループが繰り返されるたびにテキスト領域を更新するのではなく、タスクのすべての実行が完了したときにのみテキストを更新するように見えます。なぜこれが発生するのですか、どうすれば解決できますか?

4

6 に答える 6

4
private JTextArea outputText = new JTextArea();

public void DoEverything() {
    String output = "";
    for(int i = 0; i <= 10; i++) {
        output += TaskObject.someLongTask(i);
        appendNewText(output);
    }
}

public void appendNewText(String txt) {
  SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        outputText.setText(outputText.getText + txt);
       //outputText.setText(outputText.getText + "\n"+ txt); Windows LineSeparator
     }
  });
}
于 2011-07-21T10:22:01.243 に答える
2

UIを更新する前にコードの実行を待機しているSwingスレッドを使用している可能性があります。そのループには別のスレッドを使用してみてください。

public void DoEverything() {
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      String output = "";
      for(int i = 0; i <= 10; i++) {
        output += TaskObject.someLongTask(i);
        outputText.setText(output);
      }
    }
  });
}
于 2011-07-21T10:11:20.703 に答える
2

初期スレッドと呼ばれるスイング基本スレッドを使用しています。代わりにワーカースレッドを使用してください。ワーカースレッドにSwingWorkerを使用してみてください。

詳細については、次のリンクを参照してください:http: //docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

于 2012-09-24T06:55:41.197 に答える
1

投稿で述べられているように、EDT(イベントディスパッチスレッド)をブロックしないことが重要です。以下の私の例では、実際の作業はEDTスレッドから開始され、ボタンをクリックしてActionListenerから開始されます。イベントディスパッチスレッドから分離されるように、別のスレッドでラップする必要があります。したがって、EDTはブロックされません。

また、別のスレッドからUIを更新する場合は、SwingUtilities.invokeLater()を実行する必要があることに注意してください。以下のコード例は、私の元のコードから少し簡略化されています。私は実際に複数のスレッドを使用して複数のタスクを並行して実行しており、それらの各スレッドでupdateProgress()が呼び出され、最新のステータスを追加してTextAreaを更新します。

完全なソースコードはここにあります:https ://github.com/mhisoft/rdpro/blob/master/src/main/java/org/mhisoft/rdpro/ui/ReproMainForm.java

btnOk.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
    //Don't block the EDT, wrap it in a seperate thread
    DoItJobThread t = new DoItJobThread();
    t.start();

  } 
});


class DoItJobThread extends Thread {
    @Override
    public void run() {
       //do some task 
       // output the progress
       updateProgress();    
    }
}


public void updateProgress(final String msg) {
    //invokeLater()
    //This method allows us to post a "job" to Swing, which it will then run
    // on the event dispatch thread at its next convenience.

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Here, we can safely update the GUI
            // because we'll be called from the
            // event dispatch thread
            outputTextArea.append(msg);
            outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
            //labelStatus.setText(msg);
        }
    });

}
于 2014-11-27T04:53:01.243 に答える
0

DoEverything()の本体を独自のスレッドで実行します。

class SimplifiedClass extends JApplet {

    private JTextArea outputText;
    // Lots of methods
    public void DoEverything() {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                String output = "";
                for(int i = 0; i <= 10; i++) {
                    output += TaskObject.someLongTask(i);
                    outputText.setText(output);
                }
            }
        }
    }
}
于 2021-06-04T06:01:08.877 に答える
-1

outputText.setText(output)の後にoutputText.validate()を使用してみてください

私も似たような私のプログラムでこれを試しました。何らかの理由で、のThread.sleep(delay)直後にあるを使用するoutputText.setText("dsfgsdfg")と、たとえaを使用してもoutputText.validate()、ユーザーは出力を見ることができません。それは最も奇妙なことです。setTextこれは、メソッドが呼び出されようとした後にコードが読み取られたかのようです。それからsleepメソッドをヒットし、それはすべて地獄に行きます。

于 2012-05-17T23:53:42.190 に答える