我在点击按钮时设置JLabel时遇到了这个问题,就像一个加载图标。执行p.make()
方法,但在Method返回Label可见后,Label仍然不可见。
有人可以解释发生了什么吗?
的actionPerformed:
String[] args = {jTextFieldDrgzusatzVariable.getText(),jTextFieldAusgabe.getText(),"C:\\CPOracle",jTextFieldKatalog.getText()};
this.jLblLoading.setVisible(true);
if(jLblLoading.isVisible()){
try{
new P21Make(args[0],args[1],args[2],args[3]).make();
}catch(Exception e){
e.printStackTrace();
}
}
答案 0 :(得分:5)
原因很简单:Swing是单线程的(有关详细信息,请参阅Swing concurrency tutorial)。
在Swing线程上调用actionPerformed
方法会发生什么( E (通风口) D (ispatch) T 强>(hread))。
this.jLblLoading.setVisible(true);
到达语句后,它会立即将jLblLoading
标记为可见。但是,这对UI没有任何影响。在可见性更改产生任何影响之前,需要重新绘制UI。此重绘在EDT上预定(与立即执行的不同)。
这解释了为什么你的
if(jLblLoading.isVisible()){
检查成功,您仍然没有看到UI中的差异。该组件被标记为可见,但重绘仍处于待处理状态。重新绘制将保持待定状态,直到EDT再次可用。由于当前占用EDT的内容是actionPerformed
调用,因此actionPerformed
方法中的其余代码将在重绘之前执行(意味着在您看到UI中的更改之前)。< / p>
使用其他线程的解决方案确实可以解决这个问题。但是,如果new P21Make(...).make()
不影响UI,则只能使用它。如果该语句以任何方式与Swing组件交互,则应该在EDT上执行。在这种情况下,另一种方法是将语句包装在SwingUtilities#invokeLater
调用中。
答案 1 :(得分:1)
您应该考虑使用SwingUtilities.invokeLater
来允许修改gui的操作完成。
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html