3

我有两个问题:

  1. 如何检查互联网连接是打开还是关闭?我正在使用 Html Unit,并且正在使用 Windows。

  2. 我想制作一个 JLabel,在我的 JFrame 中说明 Internet 连接的可用性。就像是:

while(true)
{
    if(isOnline()) label.setText("online");
    else label.setText("offline");
}

但我认为我需要 2 个独立线程,但我如何创建这 2 个线程并在它们之间进行通信并实现这一点?

4

2 回答 2

2

这里回答了一个类似的问题:how-to-check-if-internet-connection-is-present-in-java

要完成问题的第二部分,我想您可以调用包装在 SwingWorker 线程中的 java.util.Timer 中的InetAddress.isReachable方法来定期轮询连接。

于 2011-08-24T23:14:46.043 回答
2

while (true)对您的资源有点苛刻,应该在那里暂停约 10 秒。这并不需要像股票价格行情一样准确和实时。

使用 Swing,规则是在事件调度线程上不做任何花费时间的事情。后台任务或其他长时间运行的操作永远不应在其上运行。

对于您的特定情况,这适用:

由于非 AWT 事件而必须更新 GUI 的程序:

例如,假设一个服务器程序可以从可能在不同机器上运行的其他程序获取请求。这些请求可以随时出现,它们会导致在某个可能未知的线程中调用服务器的方法之一。该方法如何更新 GUI?通过在事件调度线程中执行 GUI 更新代码。

所以我要做的是设置一个计划任务,每隔 10 秒检查一次 Internet 连接的可用性,事件调度线程开始 - 这可能最好在你的main方法中立即设置。另一方面,GUI 的更新应该发生事件分派线程上。这是一个Runnable可以对您的标签进行更新的建议。ConnectionChecker后面我会解释。我们使用 a 执行它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");
            }
        });
    }
}

现在我们必须在 main 方法中设置一个定期执行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 怎么样。如果您(正确)连接到 Internet,则此查询将成功。否则,它最终会抛出一些异常。通过连接,下载应该在 5 秒内完成 - 如果不是,那么超时连接尝试是安全的。Updater无论哪种方式,如果下载没有及时成功,您将收到一个异常。使用简单URLConnection或类似的方式进行下载。

于 2011-08-24T23:42:48.277 回答