[英]How do I make a GUI that looks like the attached picture of a simple stock market app?
[英]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 result
的String
。 像這樣
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.