【发布时间】:2020-05-01 22:00:52
【问题描述】:
所以我有这个程序应该最初使用 objectinputstream 从服务器接收数据。然后程序应将接收到的数据插入 ArrayList 并使用选项更新屏幕上的组合框。所有这些都很好,我只是把它放在这里作为上下文。
我遇到的问题是,一旦 JFrame 已加载,我希望 GUI 每 10 秒使用来自服务器的新数据更新一次,但它不起作用。我尝试过使用 swing.timer、ScheduledExecutorService.scheduleAtFixedRate 和 TimerTask,但似乎都不起作用。程序只是冻结(特别是 gui),控制台中没有显示任何错误,也没有抛出异常。
在下面的代码示例中,我将我当前的尝试以及我之前的一些尝试作为 cmets。
代码:
构造函数和设置函数:
public class UserMainGUI extends javax.swing.JFrame {
/**
* Creates new form UserMainGUI
*/
ArrayList<String> data;
JSONParser jsonParser;
ArrayList<String> weatherStationNames;
UserConnection connection;
UpdateDataTimerTask udtt;
Timer timer;
ActionListener taskPerformer;
public UserMainGUI() {
initComponents();
this.data = null;
jsonParser = new JSONParser();
udtt = new UpdateDataTimerTask();
}
public void setupGUI(UserConnection newConnection) //throws InterruptedException
{
connection = newConnection;
if(connection.WeatherStationConnectionCheck())
{
weatherStationOnline.setText("Select a weather station:");
System.out.println("First part working");
data = connection.getWeatherStationData();
if(data != null)
{
parseData();
updateData();
/*taskPerformer = (ActionEvent evt) -> {
data = connection.getWeatherStationData();
System.out.println("updated data: " + data);
parseData();
};
timer = new Timer(10000,taskPerformer);
timer.start(); */
//Thread.sleep(5000);
}
}
else
{
weatherStationComboBox.setVisible(false);
}
}
更新数据功能:
public void updateData()
{
taskPerformer = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
data = connection.getWeatherStationData();
System.out.println("updated data: " + data);
SwingUtilities.invokeLater(() -> {
parseData();
});
}
};
timer = new Timer(10000,taskPerformer);
timer.start();
/*Thread t = new Thread(new Runnable(){
public void run(){
data = connection.getWeatherStationData();
System.out.println("updated data: " + data);
SwingUtilities.invokeLater(() -> {
parseData();
});
try
{
java.lang.Thread.sleep(10000);
}
catch(Exception ex)
{
//System.err.println("Couldn't update data: " ex)
}
}
});
t.start(); */
/*Runnable retrieveRunnable = new Runnable()
{
@Override
public void run() {
try
{
data = connection.getWeatherStationData();
System.out.println("updated data: " + data);
parseData();
}
catch(Exception ex)
{
System.err.println("Could not update data: " + ex);
}
}
};
ScheduledExecutorService executor = Executors.newScheduledThreadPool(20);
executor.scheduleAtFixedRate(retrieveRunnable, 0, 10, TimeUnit.SECONDS); */
}
【问题讨论】:
-
有点,我需要定期运行,而不是在单击按钮时运行,但这是朝着正确方向迈出的一步。
-
您“可以”使用
SwingWorker从服务器请求和解析数据并将其“发布”到 UI。您可以使用ScheduledExecutorService在规定的延迟后执行它(因为SwingWorker实现了Runnable接口) - 这里的重点是 - 如果您在事件调度线程上执行长时间运行或阻塞操作,Swing 是单线程的,它会冻结你的用户界面 -
更多帮助请发帖minimal reproducible example。避免依赖数据库(硬键一些测试数据)并使用
sleep模拟长时间处理
标签: java swing client-server