【问题标题】:How to update Swing GUI in realtime - JAVA如何实时更新 Swing GUI - JAVA
【发布时间】:2022-01-18 04:06:54
【问题描述】:

我正在编写一个 java 程序来获取实时股票数据。我使用 URL 类从 yahoo Finance 获取信息。我可以使用股票类获得所需的所有信息。但是,我希望 GUI 通过调用获取股票价格的方法每隔一秒或半秒更新一次股票价格的值,并每秒更新 JLabel 中的值。所以本质上,我如何通过每秒调用一个方法来更新 Swing GUI 中的值?谢谢。

【问题讨论】:

  • 使用Swing Timer 安排更新。
  • 使用SwingWorker 执行长时间运行的操作(例如从 URL 获取数据)并将其发布回 EDT。您可以使用ExecutorService 安排这些活动,或者简单地在SwingWorker 中循环

标签: java swing url


【解决方案1】:

您可以通过多种方式实现这一目标。 Swing Timer 是在指定延迟后生成回调(进入事件调度线程)的不错选择。

但您可能想要安排一个回调来执行请求,一旦完成,更新 UI 并安排另一个回调。关键是,实际请求的调用/处理时间可能比您在调用之间分配的时间长。

以下使用SwingWorker 执行实际的“工作”,使用 1-5 秒之间的随机延迟,一旦完成,它会通知“观察者”一些新状态(在这种情况下,只是一些好消息)。

一旦工作人员完成,就会安排一个新工作人员,使用 ScheduledExecutorService(尽管您可以使用 Swing Timer 手动完成)

Concurrency in Swing

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;

public class Test {
    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

        private JLabel label;

        public TestPane() {
            setBorder(new EmptyBorder(16, 16, 16, 16));            
            label = new JLabel("Nothing happening here, just waiting for stuff");
            setLayout(new GridBagLayout());
            add(label);

            startNextWorker();
        }

        protected void startNextWorker() {
            ExecutorWorker worker = new ExecutorWorker(new ExecutorWorker.Observer() {
                @Override
                public void workerDidUpdate(String message) {
                    label.setText(message);
                }
            });
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (worker.getState() == SwingWorker.StateValue.DONE) {
                        worker.removePropertyChangeListener(this);
                        startNextWorker();
                    }
                }
            });
            service.schedule(worker, 1500, TimeUnit.MILLISECONDS);
        }

    }

    public class ExecutorWorker extends SwingWorker<Void, String> {

        public interface Observer {
            public void workerDidUpdate(String message);
        }

        private Random rnd = new Random();
        private Observer observer;

        public ExecutorWorker(Observer observer) {
            this.observer = observer;
        }

        @Override
        protected Void doInBackground() throws Exception {
            publish("Starting some new work, back in a seocnd");
            Thread.sleep(1000 + rnd.nextInt(5000));
            publish("All the work is now done");
            return null;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String messages : chunks) {
                observer.workerDidUpdate(messages);
            }
        }

    }
}

【讨论】:

    猜你喜欢
    • 2011-08-10
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多