[英]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 result
的String
。 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.