我引用了this previous question以及其他资源,但无法让CountDownLatch正常工作。
背景: mainFrame创建了一个名为dataEntryFrame的新框架。当单击dataEntryFrame“提交”按钮时,添加到数据库中的记录和dataEntryFrame将被清除。此时,mainFrame应该清除并重新加载一个显示所有记录的jList。
问题:当dataEntryFrame加载时,java冻结,dataEntryFrame组件永远不会加载。我不能通过这一部分...然后,在DataEntryFrame中,CountDownLatch应该只在单击submit按钮、成功地将记录添加到数据库表并释放自身之后递减。或者当用户单击cancel时...
代码:来自MainFrame
clearList();
CountDownLatch dataEntryDone = new CountDownLatch(1);
DataEntryFrame f = new DataEntryFrame(dataEntryDone);
Thread newThread = new Thread(f);
newThread.start();
dataEntryDone.await();
reLoadList();代码:来自DataEntryFrame
public void run(){
initComponents();
loadOtherData();
this.setVisible(true);
}
void submit(){
addRecord();
this.dispose()
dataEntryDone.countDown();
}发布于 2010-05-31 07:29:47
为dataEntryFrame使用新线程并阻塞mainFrame与Swing线程模型背道而驰。在Swing中,对Swing中的UI组件的所有调用都必须发生在事件调度线程上。要验证在开发过程中是否发生了这种情况,可以安装一个重绘管理器,该管理器在检测到正在从另一个线程使用UI组件时抛出异常。参见FEST - Testing that access to GUI components is done in the EDT。为了确保在EDT上发生一些事情,您可以使用SwingUtilities.invokeAndWait。
您的主框架没有(也不应该!)必须等待数据输入帧,而不是CountDownLatch,让数据输入帧在完成时向MainFrame触发一个事件,以便MainFrame可以采取适当的操作,如刷新列表。
为了把事情弄得更糟,最好不要在事件分派线程上完成将数据保存到数据库和获取列表数据的操作。取而代之的是,使用SwingWorker在它们自己的线程中执行这些操作。然而,与必须从EDT访问所有UI组件的规则不同,后台处理的这一规则并不是硬性的、快速的,但建议用于维护响应式UI -如果与数据库之间的数据传输需要任意长度的时间,并且是在UI线程(EDT)上完成的,则UI将冻结。
看见
Worker Threads and SwingWorker
上的
https://stackoverflow.com/questions/2939881
复制相似问题