2016-03-02 53 views
1

我寫與Swing GUI程序,我有一類以下兩種方法:搖擺 - 從執行,直到前面的方法停止的方法是完全

private void addMessageToLog(MessageType type, String message) { 
    if ((type.equals(MessageType.DELAYED_ERROR)) || (type.equals(MessageType.DELAYED_INFO)) || (type.equals(MessageType.DELAYED_SUCCESS))) { 
     Timer timer = new Timer(500, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       getModelObserver().createMessage(type, message); 
      } 
     }); 
     timer.setRepeats(false); 
     timer.start(); 
    } 
    else { 
     getModelObserver().createMessage(type, message); 
    } 
} 

private String getCommand(String instruction, String error) { 
    String command = ""; 
    while (!isValid(command)) { 
     addMessageToLog(MessageType.INFO, instruction); 
     command = getModelObserver().getCommand(); 
     checkCommand(command, error); 
    } 
    return command; 
} 

addMessageToLog可如果是「延遲加延遲消息類型'被使用。這可以正常工作,但如果我在撥打addMessageToLog後立即致電getCommand,那麼getCommand內部的非延遲addMessageToLog將在先前稱爲延遲之前執行。

例子:

addMessageToLog(MessageType.DELAYED_INFO, "Delayed message") 
getCommand("Not delayed", "Error") 

輸出:

Not delayed 
Delayed message 

而我想:

*0.5 second pause* 
Delayed message 
Not delayed 

有沒有辦法舉行的getCommand直到addMessageToLog執行完成?

我遇到了​​選項,但我不太瞭解它,並且不確定它是否可以在此實例中使用。

+0

請注意,Swing是單線程的,而不是線程安全的,這意味着您不應該因爲任何原因(比如調用Thread.sleep)或者在EDT上下文之外更新UI來阻止UI。查看[併發中的Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)以獲取更多詳細信息 – MadProgrammer

回答

1

有一種叫做忙等待的方式。 Busy Waiting on Wikipedia

實現它這樣的:

  1. 創建一個領域,即確保addMessageToLog已被執行。

    private static boolean ready = false;

  2. 如果addMessageToLog圓滿落幕,將該字段設置爲true。

    private String getCommand(String instruction, String error) { 
    [...] 
    ready = true; 
    return command; 
    

現在你可以使用這個方法是這樣的:

private String getCommand(String instruction, String error){ 
    while(!ready){sleep(1);} //Busy waiting 
    [...] 

另一種方法是調用getCommand在addMessageToLog法。