---此项目旨在更新Jsoup
每2秒从网站解析的股票报价清单。
程序:
使用JSOUP提取价格报价清单(已经完成并存储在String变量(Stock
)中(已完成)
创建Jframe,JPanel,TextArea。在TextArea上粘贴Stock
。因此,stockquote可以显示在Jframe-textArea上。 (完成)
让TextArea每2秒(做一次)更新变量stock
代码:
public void run() { // Just conduct the Parsing
try {
Parsing();
} catch (Exception ex) {
Logger.getLogger(Stock2.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void Parsing() throws Exception
{
}//Jsoup code .Parsing the element from website and stored in String `Stock`
主要代码在这里工作:主要方法
在main中,在这里创建Jframe,panel,textarea。然后,将stock
粘贴到JLabel上。
public static void main(String[] args) throws Exception {
// Timer timer = new Timer();
//timer.schedule(new Stock2(), 2000, 2000);
// javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
// public void actionPerformed(ActionEvent e) {
Stock2 stock3=new Stock2();
stock3.run();
final JFrame frame = new JFrame("Stock");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
///------------------------------
frame.setLayout(new BorderLayout());
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
///------------------------------
final JPanel panel = new JPanel();
///------------------------------
JTextArea textArea = new JTextArea(25,40);
///------------------------------
JScrollPane scroll= new JScrollPane(textArea);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
///------------------------------
textArea.setFont(new Font("Serif",Font.BOLD,16));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setOpaque(false);
textArea.setEditable(false );
// textArea. append("g");
textArea.setSize( textArea.getPreferredSize() );
textArea.setText(String.valueOf(stock));
//textArea. insert(" ", 5);
// textArea.setTabSize(50);
///------------------------------
frame.add(panel);
panel.add(scroll);
// frame.add(scroll);
frame.pack();
// frame.setVisible(true);
}
**搜索之后,我知道我应该使用Swing Timer
。但是我知道要放在哪里(主要?运行?)。此外,我尝试工作并添加到主要方法。但是发生错误。如何解决? **
答案 0 :(得分:3)
你想每2秒做一次任务,所以Swing Timer似乎是这样做的方法,但由于任务涉及查询互联网的内容,这个过程需要花费大量的时间,如果像Swing Timer那样在GUI事件线程上运行,可能会冻结你的GUI。相反,您应该使用SwingWorker,并且在SwingWorker内部使用java.util.Timer而不是Swing Timer,因为您将离开Swing事件线程,重复调用代码以获取您需要的数据,以及然后使用SwingWorker的发布/处理方法对将信息传递给GUI。查看教程Concurrency in Swing以获取有关如何执行此操作的详细信息,事实上,您可能会创建SwingWorker<Void, String>
,以便发布/进程知道它是您希望传输的文本数据
另一个不相关的问题是你有太多代码,静态main方法中的GUI代码太多,如果没有重构,你将会有一个很难调试的程序,测试和维护。通过为每个职责创建单独的类来解决此问题。
其他问题:
例如:
import java.awt.BorderLayout;
import java.awt.Font;
import java.util.List;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class StockEg {
// main method starts Swing event thread and
// calls create and show
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
// create pertinent classes and start them running. that's it
private static void createAndShowGui() {
// create and display GUI
StockGui stockGui = new StockGui();
JFrame frame = new JFrame("StockEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(stockGui.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// create worker and hook up with GUI
MyWorker myWorker = new MyWorker(stockGui);
myWorker.execute(); // start worker
}
}
// gui class
class StockGui {
private static final int TA_ROWS = 20;
private static final int TA_COLS = 40;
private static final Font TA_FONT = new Font(Font.SERIF, Font.BOLD, 16);
private JTextArea textArea = new JTextArea(TA_ROWS, TA_COLS);
private JPanel mainPanel = new JPanel(new BorderLayout());
public StockGui() {
textArea.setFont(TA_FONT);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
mainPanel.add(scrollPane, BorderLayout.CENTER);
}
// get main JPanel that holds everything
public JPanel getMainPanel() {
return mainPanel;
}
// allow outside classes to add text to JTextArea
public void appendText(String text) {
textArea.append(text);
}
}
// SwingWorker to run long-running process
class MyWorker extends SwingWorker<Void, String> {
private static final long PERIOD = 2000; // for timer
private StockGui stockGui; // gui reference
// non-GUI class that parses web page
private MyJSoupParser myJSoupParser = new MyJSoupParser();
public MyWorker(StockGui stockGui) {
this.stockGui = stockGui; // hook up gui reference
}
@Override
protected Void doInBackground() throws Exception {
// create java.util.Timer
java.util.Timer myTimer = new java.util.Timer(true);
// start timer with task
myTimer.scheduleAtFixedRate(new MyTask(), 0, PERIOD);
return null;
}
// method to send text to the GUI
@Override
protected void process(List<String> chunks) {
for (String chunk : chunks) {
stockGui.appendText(chunk + "\n");
}
}
// timer task that extracts text from the JSoup parser
// and then calls publish to send text to process method and GUI
private class MyTask extends TimerTask {
@Override
public void run() {
String parsedText = myJSoupParser.getText();
publish(parsedText);
}
}
}
// dummy class just for demo purposes
class MyJSoupParser {
private int dummyCounter = 0;
public String getText() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
return "Parsed Text: " + dummyCounter++;
}
}