while (true)
はリソースに少し厳しいため、10 秒程度の一時停止が必要です。これは、株価ティッカーほど正確でリアルタイムである必要はありません。
Swing では、イベント ディスパッチ スレッドで時間がかかることは何もしないというルールがあります。バックグラウンド タスクやその他の長時間実行される操作は、決して実行しないでください。
あなたの特定のケースでは、これが適用されます:
非 AWT イベントの結果として GUI を更新する必要があるプログラム:
たとえば、サーバー プログラムが、別のマシンで実行されている可能性のある他のプログラムから要求を取得できるとします。これらのリクエストはいつでも来る可能性があり、その結果、サーバーのメソッドの 1 つが不明なスレッドで呼び出されます。そのメソッドはどのように GUI を更新できますか? イベントディスパッチスレッドで GUI 更新コードを実行する。
だから私がすることは、イベントディスパッチスレッドから10秒ごとにインターネット接続の可用性をチェックするスケジュールされたタスクを設定することです-これはおそらくmain
メソッドですぐに設定するのが最善です. 一方、GUI の更新は、イベント ディスパッチ スレッドで行う必要があります。Runnable
これは、ラベルの更新を行うことができるの提案です。後ほど説明しますConnectionChecker
。を使用して実行しExecutorService
、タイムアウトを 5 秒に設定します。が 5 秒以内に成功した場合ConnectionChecker
は接続されていますが、それ以外の場合は接続されていません。JLabel
この結果は、 を使用してイベント ディスパッチ スレッドでを更新するために使用されますSwingUtilities#invokeLater
。
public static class Updater implements Runnable {
private final JLabel label;
private final ExecutorService executor;
/* constructor left out */
public void run() {
boolean connected = false;
Future<?> connHandle = executor.submit(new ConnectionChecker());
try {
connHandle.get(5, TimeUnit.SECONDS);
connected = true;
} catch (TimeOutException ex) {
/* connected = false; */
}
catch (InterruptedException ex) {
/* Let it be handled higher elsewhere */
Thread.currentThread().interrupt();
} catch (CancellationException ex) {
/* happens only if you actively cancel the Future */
} catch (ExecutionException ex) {
/* connected = false */
}
final boolean result = connected;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (result)
label.setText("online");
else
label.setText("offline");
}
});
}
}
Updater
ここで、JLabel と ExecutorService も作成する main メソッドで定期的に実行されるように設定する必要があります。
public static void main(String... args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
JLabel label = ...;
Updater updater = new Updater(label, executor);
executor.scheduleAtFixedRate(updater, 0, 10, TimeUnit.SECONDS);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//GUI initialization code
}
});
}
最後に、について推論しましょうConnectionChecker
。これを行う方法はたくさんあります。手っ取り早く汚い解決策は、今後数年間存続する可能性が高い Web ページを単純に取得することです。www.google.com はどうでしょう。インターネットに (正しく) 接続されている場合、このクエリは成功します。そうしないと、最終的に何らかの例外がスローされます。接続があれば、ダウンロードは 5 秒以内に完了します。そうでない場合は、接続の試行をタイムアウトしても問題ありません。Updater
いずれにせよ、ダウンロードが時間内に成功しなかった場合、例外が発生します。URLConnection
ダウンロードにはシンプルなものを使用してください。