我有一个JAVA程序的一部分,你点击一个按钮,actionListener应该经历以下过程;
按照以下
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
答案 0 :(得分:2)
这是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
});