在 Swing 界面中显示来自外部网站的实时数据?

Display real time data from external website in Swing interface?

我试过用谷歌搜索网络,但每个问题似乎都与网络开发有关。我只是想知道是否有可能从不是我的网站上每秒或每 10 秒更新一次的互联网(游戏结果和游戏事件)中获取数据,并将其显示在 Java 带有Swing库界面的桌面客户端?如果是,最好的方法是什么?

谢谢你

是的,你可以做到。您应该使用 java.net 包来处理网络。

数据获取取决于您要从中获取数据的站点,例如:

  • 如果站点有 API,例如 Stack Overflow,您应该使用它。
  • 如果数据显示在页面上,您可以使用像 jsoup 这样的解析器(当然,如果页面是 html)

我在请求时而不是在计时器上获取股票数据,但您可以查看我的代码并了解我如何获取股票数据。

JPanel 的外观如下。右边是面板

这是 HistoricalDataRunnable class。

package com.ggl.stock.picker.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.SwingUtilities;

import com.ggl.stock.picker.model.Company;
import com.ggl.stock.picker.model.StockDay;
import com.ggl.stock.picker.model.StockHistory;
import com.ggl.stock.picker.model.StockPickerModel;
import com.ggl.stock.picker.view.StockPickerFrame;

public class HistoricalDataRunnable implements Runnable {

    private static final String URLString = 
                  "http://www.google.com/finance/historical?output=csv&q=";

    private Company company;

    private StockPickerFrame frame;

    private StockPickerModel model;

    public HistoricalDataRunnable(StockPickerFrame frame,
            StockPickerModel model, Company company) {
        this.frame = frame;
        this.model = model;
        this.company = company;
    }

    @Override
    public void run() {
        InputStream is = null;
        BufferedReader br = null;

        try {
            String symbol = company.getStockSymbol();

            URL url = new URL(URLString + symbol);
            URLConnection hc = url.openConnection();
            hc.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; "
                    + "Intel Mac OS X 10.4; en-US; rv:1.9.2.2) "
                    + "Gecko/20100316 Firefox/3.6.2");
            is = hc.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            processCSVFile(br);
        } catch (MalformedURLException e) {
            e.printStackTrace();
            String message = e.getMessage();
            message = "<html>" + message;
            setMessageLabel(message);
        } catch (IOException e) {
            String message = e.getMessage();
            message = "<html>" + message;
            setMessageLabel(message);
        } finally {
            closeReaders(is, br);
        }
    }

    private void processCSVFile(BufferedReader br) throws IOException {
        String line = "";
        int count = 0;
        StockHistory history = new StockHistory(company);
        while ((line = br.readLine()) != null) {
            if (count > 0) {
                StockDay stockDay = createStockDay(line);
                if (stockDay != null) {
                    history.addStockDay(stockDay);
                }
            }
            count++;
        }
        if (history.calculateNumbers()) {
            model.addStockHistory(history);
            addStockHistory();
            setMessageLabel(" ");
        } else {
            String message = "<html>There is no data for "
                    + company.getCompanyName();
            setMessageLabel(message);
        }
    }

    private StockDay createStockDay(String line) {
        String[] parts = line.split(",");
        if (parts[1].equals("-"))
            return null;

        double open = Double.valueOf(parts[1]);
        double high = Double.valueOf(parts[2]);
        double low = Double.valueOf(parts[3]);
        double close = Double.valueOf(parts[4]);
        long volume = Long.valueOf(parts[5]);
        return new StockDay(parts[0], open, high, low, close, volume);
    }

    private void addStockHistory() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.addStockHistory();
            }
        });
    }

    private void setMessageLabel(final String text) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.setMessageLabel(text);
                ;
            }
        });
    }

    private void closeReaders(InputStream is, BufferedReader br) {
        try {
            if (br != null)
                br.close();
            if (is != null)
                is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此 class 与 Google 建立 URL 联系,returns 历史股票信息。此信息在 StockHistory 实例中捕获,并存储在 StockPickerModel 实例中。

User-Agent 属性 设置为模拟浏览器。某些网站不允许程序访问其 Web 服务器。通过设置 User-Agent 属性,你可以伪装成一个网络浏览器。你的程序应该尊重网络服务器,不要提交太多请求。多少取决于网络服务器。

这 class 也会更新视图。我们知道请求何时完成的唯一方法是 HistoricalDataRunnable 方法收到来自 Google 的响应。更新模型和视图就靠这个class了。

由于这个 class 在一个单独的线程中 运行,我们必须调用 SwingUtilities invokeLater 方法来执行任何 Swing GUI 命令。这就是将 addStockHistory 和 setMessageLabel 方法包含在 invokeLater 方法中的原因。

此 class 显示 JLabel 消息中的任何错误。 Google 可能不会保留库存。股票可能没有任何股票日价值。显示这些错误消息。

要查看其余代码,请查看我的 Stock Picker Using Java Swing 文章。