1

そのようなコード:

private void log(String message) {
    LogBox.append(message + "\n");
}

private void log(Exception e) {
    log(e.getMessage());
}

private void ConvertButtonActionPerformed(java.awt.event.ActionEvent evt) {
    String url = UrlBox.getText();
    if (url.isEmpty()) {
        log("Empty URL");
        return;
    }
    LogBox.setText("");
    try {
        log("URL "+url+" accepted. Trying to download...");
        String content = URLConnectionReader.getText(url);
        log("Downloaded. Parsing the content...");
        //
    } catch (Exception e) {
        log(e);
    }
}

各呼び出しの直後に各メッセージをLogBox( ) に出力する必要がありますが、終了時にのみ出力します。JTextArealogURL ... acceptedURLConnectionReader.getText(url)

即時出力を行うにはいくつかの方法がありました。

  • Visual Basic 6 および .NET の Application.DoEvents
  • Delphi の Application.ProcessMessages

即時出力を行う簡単な方法はありますか? DoEvents と Java でこれを行う方法についての質問を勉強していましたが、マルチスレッドから Java を学び始めるのは正しいアプローチではないと思います。

4

2 に答える 2

5

ダウンロードを行うためにa を作成しSwingWorkerます: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html


の役割は、ActionListenerユーザーのアクションをリッスンし、プログラムによるそのアクションへの応答を開始することです。

場合によっては、プログラムの応答が非常に速く、GUI のみが関係することがあります。たとえば、電卓アプリでは、現在の式の結果を計算してテキスト ボックスに書き込む "equals" ボタンにリスナーをアタッチすることができます。これはすべて、リスナー メソッド内で行うことができます (ただし、テストのために動作を分離したい場合があります)。

ユーザー アクションへの応答が、ファイルのダウンロードや解析など、長時間実行されるプロセスを開始することである場合、UI がフリーズするため、リスナー本体内でこれを実行したくありません。代わりに、リスナー内から情報 (この場合は URL 値) を収集しSwingWorker、プログラムの応答を処理するために a を起動します。

私のコメントでは、 の後のすべてを に移動することを提案しgetText()ましたSwingWorker。これは、私にとって、「有効な URL があればファイルをダウンロードし、進行状況をログに記録する」という応答があるためです。私が見ているように、空の文字列のテストはその応答の一部です。空の文字列のテストをリスナー内に残したい場合は問題ありませんが、テストしにくくなります。

イベント ディスパッチ スレッドからのみ Swing コンポーネントにアクセスできるため、呼び出しをリスナーの本体内に残す必要があります。getText()その呼び出しをワーカーに移動すると、テキストボックスが更新されると同時にテキストボックスにアクセスし、データが破損する可能性があります。

于 2013-07-01T15:28:12.920 に答える
3

Concurrencyを読んでください。

SwingWorker実行時間の長いタスクにはおそらく を使用する必要があります。そうすれば、publish結果が利用可能になったときに GUI に表示できます。

于 2013-07-01T15:28:11.897 に答える