dre*_*ore 2 java swing multithreading event-dispatch-thread
我的课程中有3个小学课程.第一个扩展applet(并充当我的主要),第二个是一个线程(实现Runnable),它处理与服务器的后端后勤/通信,第三个是JPanel类,它创建GUI(这是创建的)在一个新的线程中通过调用SwingUtilities.invokeAndWait()main(applet)类.
GUI类与后端线程进行多次通信,以使数据显示在屏幕上.我的问题是GUI在后端类为它们提供数据之前显示其组件.所以,我想告诉GUI在另一个线程中调用一个方法,等待从中回听,然后显示其组件.我尝试了几种变体:
Object[] data = backend.Method1();
wait();
showComponents(data);
Run Code Online (Sandbox Code Playgroud)
在GUI类上,并放在notifyAll();后端线程的Method1的底部,但我在netbeans中发出警告(在同步上下文之外调用Object.wait),程序在java.lang.illegalmonitorstateexception运行时崩溃.我已经尝试将synchronized关键字添加到两个方法中,但这会导致程序冻结.
我(显然,我很确定)只是在学习多线程:我在这里误解了什么?
我觉得JPanel类没有实现runnable的相关性.
编辑:根据@MadProgrammer的建议,我正在使用SwingWorker,它似乎正在做的伎俩.感谢您指点我,我以前从未听说过它们.
final JLabel loading = new JLabel("loading");
loading.setVisible(true);
add(loading);
SwingWorker sw = new SwingWorker<Map<String, ArrayList<Time[]>>, Void>() {
@Override
public Map<String, ArrayList<Time[]>> doInBackground(){
System.out.println("doing");
Map<String, ArrayList<Time[]>> toReturn = dbh.getTimes(specToPass);
return toReturn;
}
public void done(){
try {
loading.setVisible(false);
Map<String, ArrayList<Time[]>> weekMap = new HashMap(this.get());
showTimes(weekMap);
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
};
sw.execute();
Run Code Online (Sandbox Code Playgroud)
如果我没有正确实施,我希望你能告诉我.再次感谢.
别.以任何方式阻止UI总是一个坏主意.这将使您的应用程序"挂起"并阻止UI更新(或响应用户的任何输入).
这会给用户带来非常糟糕的体验.
相反,使用某种类型的回调,允许数据线程根据需要将更新发送回UI.这应该允许UI在等待来自数据线程的数据时显示类似"等待"消息的内容.
您还可以使用a SwingWorker来处理数据收集,但它可能对您的所有需求都很简单,但它提供了将任何更新同步回UI的简单方法.
确保所有创建/修改/与UI的交互都在事件调度线程的上下文中完成.
有关更多详细信息,请参阅Swing中的Concurrency
更新
基本工作流程(恕我直言)应该看起来像......
loadingDone和
loadingFailed例如loadingDone方法将其传回loadingDone调用时,重新与EDT同步(使用SwingUtilities.invokeLater)并更新UI.这实际上更简单,SwingWorker它将提供内置的进度更新
| 归档时间: |
|
| 查看次数: |
911 次 |
| 最近记录: |