簡體   English   中英

如何使我的程序每小時檢查一次股市價值[java]

[英]how do I make my program check the stock market value every hour[java]

我正在編寫一個程序來檢查股票市場中的代碼,到此為止,並添加了基本的GUI。 我對如何每小時檢查一次感到困惑,如果增加則創建綠色向上箭頭,如果減少則創建紅色向下箭頭。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class QuoteTracker {
    JFrame frame;
    JPanel mainPanel;
    JLabel enterLabel;
    JLabel resultLabel;
    JTextField text;
    JTextField result;
    JButton query;
    JButton redArrow;
    JButton greenArrow;
    String url; 

    public static void main(String[] args) {
        new QuoteTracker().buildGui();

    }

    public class checkingQuote implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    checkQuote(url);                
                //if increase in value green button

                    System.out.println("Sleeping");
                    Thread.sleep(1000 * 60 * 60);
                    System.out.println("Waking");
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                    break;
                }
            }
        }

    }

    public void checkQuote(String symbol) {
        try {
            String url = "http://finance.yahoo.com/q?s=" + symbol + "&ql=0";
            this.url = url;
            Document doc = Jsoup.connect(url).get();
            Elements css = doc.select("p > span:first-child > span");
            result.setText(css.text());         
        } catch (IOException e) {

        }

    }

    public void buildGui() {
        frame = new JFrame("QuoteTracker");
        mainPanel = new JPanel();
        enterLabel = new JLabel("enter symbol ");
        resultLabel = new JLabel("result ");
        text = new JTextField(4);
        result = new JTextField(8);
        query = new JButton("query");
        query.addActionListener(new queryListener());

        mainPanel.add(enterLabel);
        mainPanel.add(text);
        mainPanel.add(query);
        mainPanel.add(resultLabel);
        mainPanel.add(result);

        frame.getContentPane().add(mainPanel);
        frame.setSize(300, 400);
        frame.setVisible(true);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    class queryListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent ev) {
            checkQuote(text.getText());
        }
    }

}

我甚至需要線程嗎? 我從來沒有做過一個嘗試添加有意義的東西。 我在想我是否需要線程或使用Java的Timer?

您也可以在主線程中使用線程和普通的while循環,但是首先,您需要啟動線程,並且該線程必須引用您的對象。

public void buildGui() {添加以下行public void buildGui() {

Thread t1 = new Thread(new checkingQuote());
        t1.start();

這將啟動您的線程,出於測試目的,我修改了checkingQuote

public class checkingQuote implements Runnable {
        int count = 0;
        @Override
        public void run() {
            System.out.println("Inside Runner");
            while (true) {
                try {
                    count++;
                    checkQuote(url);                
                //if increase in value green button

                    result.setText(""+count);
                    System.out.println("Sleeping");
                    Thread.sleep(1000);
                    System.out.println("Waking");
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                    break;
                }
            }
        }

    }

我在文本框中看到數字更改。...您可以更改獲取和顯示引號的邏輯。.但是您必須保留前一個引號的值,以與最新代碼進行比較以顯示綠色和紅色通知。 ..

在gui應用程序中,最好使用Timer ,也可以使用ScheduledThreadPoolExecutor 但是在第二種情況下,您計划的任務可能會在非GUI線程中運行。 由於無法直接從另一個線程調用ATW / Swing,因此應將對Swing的所有調用包裝到SwingUtilities.invokeLater()方法中。

還要注意,當您在GUI線程中執行持久的操作時,整個GUI會變得毫無干擾。 因此,為了獲得更好的響應性,您可以在單獨的線程中進行查詢,並在檢查引號后通過invokeLater將結果公開給Swing。 因此,您的checkQuote方法可以通過以下方式重寫:

public void checkQuote(String symbol) {
    try {
        final String url = "http://finance.yahoo.com/q?s=" + symbol + "&ql=0";
        Document doc = Jsoup.connect(url).get();
        Elements css = doc.select("p > span:first-child > span");
        final String text = css.text();
        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {
                this.url = url;
                result.setText(text);
            }
        }
    } catch (IOException e) {
        // Don't swallow exceptions
        logger.error("Something gone wrong", e);
    }
}

public void checkQuote() {
    final String symbol = text.getText();
    new Thread(new Runnable() {
        @Override public void run() {
            checkQuote(symbol);
        }
    }).start();
}

並從Timer和按鈕單擊偵聽器中調用它。

使用SwingWorker在后台執行長時間運行的任務,同時根據該長時間運行任務的一些結果更新UI。 這意味着,實際上是兩個相互通信的不同線程- 工作者線程事件調度線程(EDT)


但是在此之前,我想指出一些有關您的代碼的注釋。

  • 在EDT中調用UI的初始化。 也就是說,而不只是筆直地調用new QuoteTracker().buildGui()叫它的run方法里面Runnable傳遞給SwingUtilities.invokeLater (像這樣

  • 按照Java標准,類應以大寫字母開頭。


要在現有代碼中應用SwingWorker ,可以執行以下操作:

首先,必須將checkQuote方法放置在其他某個類(最好是服務類)中,然后修改checkQuote方法以返回設置為textfield resultString 像這樣

public Class QuoteService{
    public String checkQuote(String symbol) {
        try {
            String url = "http://finance.yahoo.com/q?s=" + symbol + "&ql=0";
            this.url = url;
            Document doc = Jsoup.connect(url).get();
            Elements css = doc.select("p > span:first-child > span");
            return css.text();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
}

然后,您可以使QuoteTracker類主要集中在應用程序的UI部分。 只需將服務對象創建為實例級別字段,即可在類中自由調用checkQuote方法。

單擊該按鈕時,調用SwingWorker。

public void actionPerformed(ActionEvent ev) {

    new SwingWorker<Void, String>() {
        @Override // this method is done in the Worker Thread
        protected Void doInBackground() throws Exception {
            while(true){ 
                String res = checkQuote(text.getText());
                publish(res); //will call the process method
                Thread.sleep(1000 * 60 * 60); //1 hour
            }
        }

        @Override // this method is done in the EDT
        protected void process(List<String> resultList){
            String res = resultList.get(0);

            if(!"".equals(res)){
                result.setText(res);
            }
        }

        @Override // this method is done in the EDT. Executed after executing the doInBackground() method
        protected void done() {
            //... clean up
        }
    }.execute();
}

請注意, done()將在doInBackground()執行完成后執行,這意味着,在我發布的代碼中,由於用於定期調用checkQuote的while循環是無限的,因此它將永遠不會執行。 只需對其進行修改,以便您可以根據需要中斷該循環

進一步閱讀: Swing中的並發

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM