while (true)
немного грубовато для ваших ресурсов, там должна быть пауза ~ 10 с.Не то, чтобы это было так точно и в режиме реального времени, как тикер цены акций.
В Swing правило состоит в том, чтобы ничего не делать, что занимает время в потоке отправки событий.Фоновые задачи или другие длительные операции никогда не должны выполняться на нем.
В вашем конкретном случае применяется :
Программы, графический интерфейс которых должен быть обновлен какрезультат событий, не относящихся к AWT:
Например, предположим, что серверная программа может получать запросы от других программ, которые могут работать на разных компьютерах.Эти запросы могут поступать в любое время, и они приводят к тому, что один из методов сервера вызывается в некотором, возможно, неизвестном потоке.Как этот метод может обновить графический интерфейс?Выполнив код обновления GUI в потоке диспетчеризации событий.
Итак, я бы настроил запланированное задание, которое проверяет наличие подключения к Интернету каждые 10 секунд off поток событий-рассылки - это, вероятно, лучше всего настроить сразу в вашем main
методе.С другой стороны, обновление GUI должно произойти в потоке отправки событий.Вот предложение для Runnable
, которое может сделать обновление на вашем ярлыке.Я объясню ConnectionChecker
позже.Мы выполняем это с помощью ExecutorService
и устанавливаем тайм-аут 5 секунд.Если ConnectionChecker
успешно в течение 5 секунд, вы подключены, в противном случае нет.Этот результат затем используется для обновления 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:
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
.Есть много способов, как вы могли бы сделать это.Быстрое и грязное решение состоит в том, чтобы просто получить веб-страницу, которая, вероятно, останется в ближайшие несколько лет - как насчет www.google.com.Если вы подключены к Интернету (правильно), этот запрос будет выполнен успешно.В противном случае он, наконец, выдаст какое-то исключение.При подключении загрузка должна быть произведена менее чем за 5 секунд - если это не так, тогда можно безопасно прервать попытку подключения.В любом случае, вы получите Исключение в вашем Updater
, если загрузка не удалась вовремя.Используйте простой URLConnection
или аналогичный для загрузки.