---该项目旨在每 2 秒更新一次由 Jsoup
从网站解析的股票报价列表。
过程:
使用 JSOUP 提取报价列表(这已经完成并存储在字符串变量 (
Stock
) 中(完成)创建 Jframe 、JPanel 和 TextArea 。将
Stock
粘贴到 TextArea 上。因此,股票行情可以显示在 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
。但我不知道该放在哪里(主要?运行?)。另外,我尝试继续工作并添加到主要方法中。但是出现错误。如何解决? **
最佳答案
您想每 2 秒执行一次任务,因此 Swing Timer 似乎是执行此操作的方法,但由于该任务涉及查询 Internet 的内容,因此此过程需要的时间非常多,如果像 Swing 计时器那样在 GUI 事件线程上运行,可能会卡住您的 GUI。相反,您可能应该使用 SwingWorker,并且在 SwingWorker 内部使用 java.util.Timer ,而不是 Swing Timer,因为您将离开 Swing 事件线程,重复调用代码以获取所需的数据,然后使用 SwingWorker 的发布/处理方法对将信息传递给 GUI。查看教程,Concurrency in Swing有关如何执行此操作的详细信息,事实上,您可能会创建一个 SwingWorker<Void, String>
这样发布/处理就会知道您要传输的是文本数据。
另一个不相关的问题是你的代码太多了,静态 main 方法中的 GUI 代码太多了,如果不重构,你的程序将很难调试, 测试和维护。通过为每个职责创建单独的类来解决此问题。
其他问题:
- 从不设置 JTextArea 的首选大小。这样做,看看当您的文本最终填满可见文本区域时会发生什么。然后再添加一些文本,JScrollPane 将不会滚动,因为您已经固定了文本区域的首选项大小。而是设置它的列和行属性。
例如:
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++;
}
}
关于java - 如何每 2 秒更新 TextArea(Jframe) 中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38416656/