为什么Java没有按时间顺序执行命令?

时间:2015-02-12 07:48:32

标签: java swing

我在点击按钮时设置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();
    }
 }

2 个答案:

答案 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