\ru\ifmo\alarm\event\StateTimer.java

package ru.ifmo.alarm.event; 
 
import java.awt.event.WindowEvent; 
import java.awt.event.WindowListener; 
import java.util.Timer; 
import java.util.TimerTask; 
 
import ru.ifmo.alarm.gui.AlarmFrame; 
 
import com.evelopers.common.exception.CommonException; 
import com.evelopers.unimod.core.stateworks.Event; 
import com.evelopers.unimod.runtime.EventProvider; 
import com.evelopers.unimod.runtime.ModelEngine; 
import com.evelopers.unimod.runtime.context.StateMachineContextImpl; 
 
public class StateTimer implements EventProvider { 
    // this class will be used to make delays during which some events could happen 
     
    public static final int BUTTON3_TIMER = 0;  // that is who wants to be stopped 
    public static final int DANGER_TIMER  = 1; 
    public static final int ALARM_TIMER   = 2; 
     
    public static final int TIMERS_NUMBER = 3; 
     
    private ModelEngine engine; 
     
    public static StateTimer stateTimer = new StateTimer(); 
     
    private Timer[] timers; 
     
    /** 
     * @unimod.event.descr button3 time finished 
     */ 
    public static final String E31 = "e31"; 
     
    /** 
     * @unimod.event.descr danger time finished 
     */ 
    public static final String E32 = "e32"; 
     
    /** 
     * @unimod.event.descr alarm time finished 
     */ 
    public static final String E33 = "e33"; 
 
//  This event is used to stop state machine when the window was closed 
//  In fact, it shouldn't be in StateTimer class! 
//  But it would be irrational to create a new event provider just for it 
    /** 
     * @unimod.event.descr window closed 
     */ 
    public static final String E34 = "e34"; 
     
    public void start(int secsRequired, int target) {       //this method will be called by some controlled object 
        if (timers[target] != null) { 
            timers[target].cancel(); 
        } 
        timers[target] = new Timer(true); 
        timers[target].schedule(new StopTimerTask(target), secsRequired * 1000); 
    } 
     
    public void init(ModelEngine engine) throws CommonException { 
        stateTimer.engine = engine;    //it lets us use then method StateTimer.stateTimer.start(...) 
        stateTimer.timers = new Timer[TIMERS_NUMBER]; 
         
        AlarmFrame.alarmFrame.addWindowListener(new WindowListener() { 
            public void windowActivated(WindowEvent e) {} 
            public void windowClosed(WindowEvent e) {} 
            public void windowClosing(WindowEvent e) { 
                stateTimer.engine.getEventManager().handle( 
                        new Event(E34), StateMachineContextImpl.create()); 
            }      
            public void windowDeactivated(WindowEvent e) {} 
            public void windowDeiconified(WindowEvent e) {} 
            public void windowIconified(WindowEvent e) {} 
            public void windowOpened(WindowEvent e) {} 
        }); 
    } 
 
    public void stopAllTimers() { 
        if (timers == null) 
            return; 
        for (int i = 0; i < TIMERS_NUMBER; i++) { 
            if (timers[i] != null) { 
                timers[i].cancel(); 
                timers[i] = null; 
            } 
        } 
    } 
     
    // throw event E31 or E32 or E33 depending on for what purpose timer is started 
    private class StopTimerTask extends TimerTask { 
        private String targetEvent; 
        StopTimerTask (int target) { 
            switch (target) { 
            case BUTTON3_TIMER: 
                targetEvent = E31; 
                break; 
            case DANGER_TIMER: 
                targetEvent = E32; 
                break; 
            case ALARM_TIMER: 
                targetEvent = E33; 
                break; 
            default: 
                targetEvent = E31; 
            } 
        } 
        public void run() { 
            StateTimer.this.engine.getEventManager().handle( 
                    new Event(targetEvent), StateMachineContextImpl.create()); 
        } 
    } 
     
    public void dispose() { 
        stopAllTimers(); 
        AlarmFrame.alarmFrame.dispose(); 
    } 
     
}