我的JAVA程序中有一个部分,您单击一个按钮,然后actionListener应该经过以下过程;
将按钮上的文本从“开始”更改为“待机”
在面板上添加标签,表明进程已开始
执行一个方法(对数据进行排序,并通过addelement将其返回给defaultListModel JList,最后
将按钮上的文本从“开始”更改为“完成”
如下所示
uploadNotamButton.addActionListener((ActionEvent e) -> {
if(e.getSource()==uploadNotamButton)
uploadNotamButton.setText("STANDBY");
progressLabel.setText("Process Has Begun, standby...");
progressLabel.setVisible(true);
uploadNotams();
uploadNotamButton.setText("COMPLETE");
});
但是,当我按下按钮时,按钮文本不会更改,标签不会显示,但是方法会执行。仅当方法完成时,按钮文本才会变为“完成”(从不显示“ STANDBY”),并且显示“过程已开始,待机”的标签(过程完成时)。
这是defaultlistmodel的功能要优先于所有内容还是我的编码经验不足?
同样,在方法中分析的数据将一次性显示在JList中,而不是一次显示每个元素。如果数据按分析方式显示在列表中,则至少表明正在发生某种情况。 defaultListModel是不可能的吗?
提前谢谢了
PG
最佳答案
这是defaultlistmodel的功能要优先于所有内容还是我的编码经验不足?
这与DefaultListModel无关,而与Swing是单线程的无关。您的长期运行过程正在Swing事件线程上运行,从而阻止该线程执行其必要的操作,包括在GUI上绘制文本和图像以及与用户进行交互。
解决方案是使用后台线程(例如可以通过SwingWorker获得的后台线程),在该后台线程中运行长时间运行的代码,将PropertyChangeListener添加到工作程序中以在完成时得到通知,然后响应此通知。
例如(代码未经测试)
uploadNotamButton.addActionListener((ActionEvent e) -> {
// if(e.getSource()==uploadNotamButton)
uploadNotamButton.setText("STANDBY");
progressLabel.setText("Process Has Begun, standby...");
progressLabel.setVisible(true);
// create worker to do background work
SwingWorker<Void, Void> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
// this is all done within a background thread
uploadNotams(); // don't make any Swing calls from within this method
return null;
}
};
// get notified when the worker is done, and respond to it
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue == SwingWorker.StateValue.DONE) {
uploadNotamButton.setText("COMPLETE");
// the code below needs to be surrounded by a try/catch block
// and you'll need to handle any exceptions that might be caught
((SwingWorker) evt.getSource()).get();
}
}
});
worker.execute(); // run the worker
});