简体   繁体   English

如何使我的程序每小时检查一次股市价值[java]

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

I am making a program to check the stock market for a symbol and I got that far, and added a basic gui to it. 我正在编写一个程序来检查股票市场中的代码,到此为止,并添加了基本的GUI。 I am stumped on how to make it check every hour and create a green up arrow if it increased and red down arrow if it decreased. 我对如何每小时检查一次感到困惑,如果增加则创建绿色向上箭头,如果减少则创建红色向下箭头。

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());
        }
    }

}

Do I even need a thread? 我甚至需要线程吗? I've never made one before and tried to add things that made sense. 我从来没有做过一个尝试添加有意义的东西。 I am thinking I either need a thread or to use java's Timer? 我在想我是否需要线程或使用Java的Timer?

You can use thread and normal while loop in main thread as well, but at the very first , you need to start you thread and that thread must refer your object. 您也可以在主线程中使用线程和普通的while循环,但是首先,您需要启动线程,并且该线程必须引用您的对象。

Add following line in public void buildGui() { public void buildGui() {添加以下行public void buildGui() {

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

This will start you thread, for testing purpose i have modified checkingQuote class 这将启动您的线程,出于测试目的,我修改了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;
                }
            }
        }

    }

I am seeing number change in the text box.... same way you can alter the logic to get and show the quotes.. but you must keep the value for previous quote to compare with the latest code to show green and red notification... 我在文本框中看到数字更改。...您可以更改获取和显示引号的逻辑。.但是您必须保留前一个引号的值,以与最新代码进行比较以显示绿色和红色通知。 ..

In gui application it is better to use Timer , also you may use ScheduledThreadPoolExecutor . 在gui应用程序中,最好使用Timer ,也可以使用ScheduledThreadPoolExecutor But in the second case notice, that your scheduled tasks may run in non-GUI thread. 但是在第二种情况下,您计划的任务可能会在非GUI线程中运行。 As you can't invoke ATW/Swing directly from another thread, you should wrap any call to Swing into SwingUtilities.invokeLater() method. 由于无法直接从另一个线程调用ATW / Swing,因此应将对Swing的所有调用包装到SwingUtilities.invokeLater()方法中。

Also notice, that when you do something durable inside GUI thread, the whole GUI becomes unrepsonsive. 还要注意,当您在GUI线程中执行持久的操作时,整个GUI会变得毫无干扰。 So, to achieve a better responsiveness, you would query in a separate thread, and expose results to Swing through invokeLater after quotes have checked. 因此,为了获得更好的响应性,您可以在单独的线程中进行查询,并在检查引号后通过invokeLater将结果公开给Swing。 So your checkQuote method may be rewritten this way: 因此,您的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();
}

and call it from Timer and from button click listener. 并从Timer和按钮单击侦听器中调用它。

Use SwingWorker to execute long running task in the background while updating the UI based on some results from that long running task. 使用SwingWorker在后台执行长时间运行的任务,同时根据该长时间运行任务的一些结果更新UI。 That means, it is actually about two different threads communicating to each other - Worker Threads and Event Dispatch Thread (EDT) 这意味着,实际上是两个相互通信的不同线程- 工作者线程事件调度线程(EDT)


But before that, I want to point some few notes about your code. 但是在此之前,我想指出一些有关您的代码的注释。

  • Invoke the initialization of your UI in the EDT. 在EDT中调用UI的初始化。 That is, instead of just straightly calling new QuoteTracker().buildGui() , call it inside the run method of a Runnable passed to SwingUtilities.invokeLater (like this ) 也就是说,而不只是笔直地调用new QuoteTracker().buildGui()叫它的run方法里面Runnable传递给SwingUtilities.invokeLater (像这样

  • Classes should start in capital letter as per the Java standard. 按照Java标准,类应以大写字母开头。


To apply SwingWorker in you existing code, you can do the following : 要在现有代码中应用SwingWorker ,可以执行以下操作:

First, you must place your checkQuote method in some other class (ideally a service class) then modify your checkQuote method to return the String that is set to the textfield result . 首先,必须将checkQuote方法放置在其他某个类(最好是服务类)中,然后修改checkQuote方法以返回设置为textfield resultString Something like this 像这样

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 "";
    }
}

You can then make your QuoteTracker class to focus mainly in the UI part of your application. 然后,您可以使QuoteTracker类主要集中在应用程序的UI部分。 Just create the service object as instance level field so that you can freely call checkQuote method within your the class. 只需将服务对象创建为实例级别字段,即可在类中自由调用checkQuote方法。

Invoke SwingWorker when the button is clicked. 单击该按钮时,调用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();
}

Note that done() will be executed after the execution of doInBackground() is finished, which means, in the code I posted, it will never be executed since the while loop used to periodically call checkQuote is infinite. 请注意, done()将在doInBackground()执行完成后执行,这意味着,在我发布的代码中,由于用于定期调用checkQuote的while循环是无限的,因此它将永远不会执行。 Just modify it so that you can interrupt that loop according to your need 只需对其进行修改,以便您可以根据需要中断该循环

Further Read : Concurrency in Swing 进一步阅读: Swing中的并发

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何制作一个看起来像一个简单的股票市场应用程序附图的GUI? - How do I make a GUI that looks like the attached picture of a simple stock market app? 如何在后台检查SQLite表的值,并每小时发送一次通知? - How do I check a value of an SQLite table in the background, and send a notification every hour? 我如何制作一个java程序来检查字符串中是否有元音? - how do I make a java program to check if there is a vowel in a string? 如何检查Java字符串中的每个值? - How do I check every value in a Java string? 我如何让我的Java程序等到在文本字段中输入值 - How do i make my java program wait until there is entered a value into the textfield 如何在Java中检查程序的更新 - How do I check my program for updates in Java 我如何使我的android程序的背景变为Java? - How do i make the background of my android program colored in java? 如何为Java程序制作最终的可执行文件? - How do I make a final executable file for my Java program? 如何从Java应用程序拨打语音电话? 如何使该程序正常工作? - How do I make a voice call from my Java app? How do I make this program work? 如何使我的程序每五秒钟重复一次声音? - How do I make my program repeat the sound every five seconds?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM