繁体   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