MVC架构下如何实现暂停:面板改色后延迟1秒恢复原色的问题
问题原因
Swing采用单线程渲染模型,所有UI组件的绘制、事件回调逻辑都运行在专属的**事件调度线程(EDT)**中:
- 调用
setBackground()修改颜色后,Swing会先往EDT的任务队列里塞一个重绘请求,不会立刻完成颜色更新 - 紧接着的
Thread.sleep(1000)直接阻塞了EDT线程,重绘请求无法被执行 - 1秒休眠结束后,又立刻把颜色改回了原始值,EDT后续执行重绘时只会渲染最后一次的颜色配置,因此看不到中间的变色效果。
解决方案
使用Swing自带的javax.swing.Timer实现延迟操作,它的回调逻辑默认运行在EDT中,不会阻塞UI渲染,修改后的代码如下:
public View(Model model){ this.model=model; initComponents(); model.addPropertyChangeListener("change", new PropertyChangeListener(){ @Override public void propertyChange(PropertyChangeEvent evt) { // 先更新为临时颜色 panelGreen.setBackground(new Color(153,255,153)); // 1000毫秒后执行回调,仅执行一次 Timer timer = new Timer(1000, e -> { jButton1.setText("hello"); panelGreen.setBackground(new Color(0,255,0)); }); timer.setRepeats(false); timer.start(); } }); }
注意事项
- 不要在EDT线程中执行任何阻塞、耗时操作,包括
Thread.sleep、IO操作、复杂计算,否则会直接导致整个界面卡死无响应 - 所有UI更新操作必须放在EDT中执行,
Swing Timer的回调默认就在EDT中,不需要额外做线程切换
内容的提问来源于stack exchange,提问作者Jeral
相关产品推荐
相关产品推荐

