Search code examples
javaswingtimersynchronizedthread-sleep

Swing - Stopping a method from executing until previous method is complete


I am writing a GUI program with Swing and I have the two following methods in a class:

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 can add a delay if a 'delayed message type' is used. This works fine, but if I have a call to getCommand immediately after an addMessageToLog call, then the non-delayed addMessageToLog internal to getCommand will be executed before the previously called delayed one.

Example:

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

Output:

Not delayed
Delayed message

Whereas I want:

*0.5 second pause*
Delayed message
Not delayed

Is there any way to hold the execution of getCommand until addMessageToLog has completed?

I have come across the synchronized option, but I don't really understand it and am unsure whether it can be used in this instance.


Solution

  • there is a way called busy waiting. Busy Waiting on Wikipedia

    implement it like that:

    1. create a field, that makes sure addMessageToLog has been executed.

      private static boolean ready = false;

    2. if addMessageToLog ended successfully, set this field to true.

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

    Now you can use this Methods like this:

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

    The other way is to call getCommand in the addMessageToLog-Method.