JDialog销毁后无法退出循环的技术问题求助
问题原因与解决方案
核心问题:线程可见性缺失
主线程的while(uwudaddy.stillrunning)循环读取的是本地缓存的stillrunning值,而Swing事件调度线程(EDT)在windowClosed方法中修改的是堆内存中的变量值。由于没有可见性保障,主线程无法感知到变量的更新,导致循环无限执行。
具体修复方案
方案1:修复可见性问题(最小改动)
给ResizeDialogSubstitute类中的stillrunning变量添加volatile关键字,强制线程每次读取该变量时从主内存获取,确保跨线程的可见性:
public class ResizeDialogSubstitute { int Width, Height; void SetWidth(int width){Width=width;} void SetHeight(int height){Height=height;} volatile boolean stillrunning = true; // 添加volatile修饰符 ResizeDialogSubstitute(){ Width=0; Height=0; } }
方案2:使用模态对话框(更优雅的实现)
完全不需要循环等待的逻辑,将对话框设置为模态,这样dialog.setVisible(true)会阻塞主线程,直到对话框关闭后才继续执行后续代码:
- 在
ResizeDialog的构造方法中添加模态设置:
ResizeDialog(int widthNow, int heightNow, ResizeDialogSubstitute UwuDaddy) { uwudaddy=UwuDaddy; this.setSize(300, 200); this.setTitle("Resize"); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setModal(true); // 设置为模态对话框 // ... 其余代码 }
- 移除
test类中的循环:
public static void main(String[] args) { ResizeDialogSubstitute uwudaddy = new ResizeDialogSubstitute(); ResizeDialog dialog = new ResizeDialog(100,100, uwudaddy); dialog.setVisible(true); // 对话框关闭后直接执行下面的代码,无需循环 System.out.println(uwudaddy.Height); System.out.println(uwudaddy.Width); }
额外的代码优化建议
- 修复未定义的布局管理器变量
c:
// 在ResizeDialog构造方法开头添加 Container c = getContentPane(); c.setLayout(new FlowLayout()); // 使用流式布局,适配组件排列
- 用
JTextField替代JTextArea(单行输入更合适):
x = new JTextField(Integer.toString(widthNow), 10); y = new JTextField(Integer.toString(heightNow), 10);
- 添加输入异常处理,避免非数字输入导致崩溃:
public void windowClosed(WindowEvent e) { System.out.println("At least I got so far"); try { uwudaddy.SetHeight(Integer.parseInt(GetNewHeight())); uwudaddy.SetWidth(Integer.parseInt(GetNewWidth())); } catch (NumberFormatException ex) { // 输入无效时设置默认值 uwudaddy.SetHeight(100); uwudaddy.SetWidth(100); } uwudaddy.stillrunning=false; }
内容的提问来源于stack exchange,提问作者Das heilige Dönerhuhn
相关产品推荐
相关产品推荐

