001    package ifs.util;
002    
003    import java.util.*;
004    
005    /**
006     * Progress bar.
007     * <br><br>
008     * Single instance class for recording the current state. It also allows recursive storing/restoring of the progress.
009     *
010     * <br><br>
011     * Use:<ul><code>
012     * Progress.getInstance().setStatus("Loading input data");<br>
013     * Progress.getInstance().setPhase("Creating variables ...", nrVariables);<br>
014     * for (int i=0;i<nrVariables;i++) {<br>
015     * &nbsp;&nbsp;&nbsp;&nbsp;//load variable here<br>
016     * &nbsp;&nbsp;&nbsp;&nbsp;Progress.getInstance().incProgress();<br>
017     * }<br>
018     * Progress.getInstance().setPhase("Creating constraints ...", nrConstraints);<br>
019     * for (int i=0;i<nrConstraints;i++) {<br>
020     * &nbsp;&nbsp;&nbsp;&nbsp;//load constraint here<br>
021     * &nbsp;&nbsp;&nbsp;&nbsp;Progress.getInstance().incProgress();<br>
022     * }<br>
023     * Progress.getInstance().setStatus("Solving problem");<br>
024     * ...<br>
025     * </code></ul>
026     *
027     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
028     * @version 1.0
029     */
030    public class Progress {
031        private String iStatus="";
032        private String iPhase="";
033        private long iProgressMax=0;
034        private long iProgressCurrent=0;
035        private Vector iListeners = new FastVector(5);
036        private Vector iSave = new FastVector(5);
037        
038        private static Progress sInstance = new Progress();
039    
040        private Progress() {}
041        
042        /** Progress instance */
043        public static Progress getInstance() { return sInstance; }
044        
045        /** Current status */
046        public String getStatus() { return iStatus; }
047        /** Sets current status */
048        public void setStatus(String status) { 
049            if (!status.equals(iStatus)) {
050                iStatus = status; fireStatusChanged(); 
051            }
052        }
053        /** Current phase */
054        public String getPhase() { return iPhase; }
055        /** Sets current phase 
056         * @param phase phase name
057         * @param progressMax maximum of progress bar
058         */
059        public void setPhase(String phase, long progressMax) {
060                iPhase = phase; iProgressMax=progressMax; iProgressCurrent=0; firePhaseChanged();
061        }
062        /** Sets current phase. Maximum of progress bar is set to 100.
063         * @param phase phase name
064         */
065        public void setPhase(String phase) { setPhase(phase, 100); }
066        /** Update progress bar. 
067         * @param progress progress between 0 and progressMax
068         */
069        public void setProgress(long progress) { 
070            if (iProgressCurrent!=progress) {
071                iProgressCurrent = progress; fireProgressChanged();
072            }
073        }
074        /** Current progress */
075        public long getProgress() { return iProgressCurrent; }
076        /** Maximum of current progress */
077        public long getProgressMax() { return iProgressMax; }
078        /** Increment current progress */
079        public void incProgress() {
080            iProgressCurrent++; 
081            fireProgressChanged();
082        }
083        /** Adds progress listener */
084        public void addProgressListener(ProgressListener listener) { iListeners.addElement(listener); }
085        /** Remove progress listener */
086        public void removeProgressListener(ProgressListener listener) { iListeners.removeElement(listener); }
087        
088        /** Save current progress to the heap memory */
089        public synchronized void save() { 
090            iSave.addElement(new Object[] { iStatus, iPhase, new Long(iProgressMax), new Long(iProgressCurrent) }); 
091            fireProgressSaved();
092        }
093        /** Resore the progress from the heap memory */
094        public synchronized void restore() { 
095            if (iSave.isEmpty()) return;
096            Object[] o = (Object[]) iSave.lastElement();
097            iSave.removeElementAt(iSave.size()-1);
098            String status = (String)o[0];
099            String phase = (String)o[1];
100            long progressCurrent = ((Long)o[2]).longValue();
101            long progressMax = ((Long)o[3]).longValue();
102            fireProgressRestored();
103            setStatus(status);
104            setPhase(phase,progressMax);
105            setProgress(progressCurrent);
106        }
107        
108        private void fireStatusChanged() {
109            for (Enumeration e=iListeners.elements();e.hasMoreElements();) {
110                ProgressListener listener = (ProgressListener)e.nextElement();
111                listener.statusChanged(iStatus);
112            }
113        }
114        private void firePhaseChanged() {
115            for (Enumeration e=iListeners.elements();e.hasMoreElements();) {
116                ProgressListener listener = (ProgressListener)e.nextElement();
117                listener.phaseChanged(iPhase);
118            }
119        }
120        private void fireProgressChanged() {
121            for (Enumeration e=iListeners.elements();e.hasMoreElements();) {
122                ProgressListener listener = (ProgressListener)e.nextElement();
123                listener.progressChanged(iProgressCurrent, iProgressMax);
124            }
125        }
126        private void fireProgressSaved() {
127            for (Enumeration e=iListeners.elements();e.hasMoreElements();) {
128                ProgressListener listener = (ProgressListener)e.nextElement();
129                listener.progressSaved();
130            }
131        }
132        private void fireProgressRestored() {
133            for (Enumeration e=iListeners.elements();e.hasMoreElements();) {
134                ProgressListener listener = (ProgressListener)e.nextElement();
135                listener.progressRestored();
136            }
137        }
138    }