001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.progress;
003
004import java.awt.Component;
005
006/**
007 * Typical use case is:
008 * <pre>
009 *   monitor.beginTask()
010 *   try {
011 *     .. do some work
012 *     monitor.worked()
013 *     monitor.subTask()/monitor.intermediateTask()
014 *     .. do some work
015 *     monitor.worked()
016 *   } finally {
017 *     monitor.finishTask();
018 *   }
019 * </pre>
020 *
021 * {@link #subTask(String)} and {@link #indeterminateSubTask(String)} has nothing to do with logical
022 * structure of the work, they just show task title to the user.
023 *
024 * If task consists of multiple tasks then {@link #createSubTaskMonitor(int, boolean)} may be used. It
025 * will create new ProgressMonitor, then can be passed to the subtask. Subtask doesn't know whether
026 * it runs standalone or as a part of other task. Progressbar will be updated so that total progress is
027 * shown, not just progress of the subtask
028 *
029 * All ProgressMonitor implementations should be thread safe.
030 *
031 */
032public interface ProgressMonitor {
033
034    public interface CancelListener {
035        void operationCanceled();
036    }
037
038    /** Ticks count used, when no other value is supplied */
039    public final int DEFAULT_TICKS = 10000;
040
041    /**
042     * Can be used with {@link #worked(int)} and {@link #createSubTaskMonitor(int, boolean)} to
043     * express that the task should use all remaining ticks
044     */
045    public final int ALL_TICKS = -1;
046
047    /**
048     * Starts this progress monitor. Must be called exactly once
049     * Ticks count is set to default value
050     * @param title title text of the task
051     */
052    void beginTask(String title);
053
054    /**
055     * Starts this progress monitor. Must be called exactly once
056     * @param title title text of the task
057     * @param ticks number of work units (see {@link #setTicksCount(int ticks)})
058     */
059    void beginTask(String title, int ticks);
060
061    /**
062     * Finish this progress monitor, close the dialog or inform the parent progress monitor
063     * that it can continue with other tasks. Must be called at least once (if called multiply times
064     * then further calls are ignored)
065     */
066    void finishTask();
067
068    /**
069     * Can be used if method receive ProgressMonitor but it's not interested progress monitoring.
070     * Basically replaces {@link #beginTask(String)} and {@link #finishTask()}
071     *
072     * This method can be also used in finally section if method expects that some exception
073     * might prevent it from passing progressMonitor away. If {@link #beginTask(String)} was
074     * already called then this method does nothing.
075     */
076    void invalidate();
077
078    /**
079     * Set the total number of work units
080     * @param ticks Number of total work units
081     */
082    void setTicksCount(int ticks);
083
084    /**
085     * Get the total number of work units
086     * @return Number of total work units
087     */
088    int getTicksCount();
089
090    /**
091     * Set the current number of work units
092     * @param ticks Number of work units already done
093     */
094    void setTicks(int ticks);
095
096    /**
097     * Get the current number of work units
098     * @return Number of work units already done
099     */
100    int getTicks();
101
102    /**
103     * Increase number of already done work units by ticks
104     * @param ticks number of ticks to add
105     */
106    void worked(int ticks);
107
108    /**
109     * Subtask that will show progress running back and forth
110     * @param title Can be {@code null}, in that case task title is not changed
111     */
112    void indeterminateSubTask(String title);
113
114    /**
115     * Normal subtask
116     * @param title Can be {@code null}, in that case task title is not changed
117     */
118
119    void subTask(String title);
120    /**
121     * Shows additional text
122     */
123
124    void setCustomText(String text);
125    /**
126     * Show extra text after normal task title. Hack for ProgressInputStream to show number of kB
127     * already downloaded
128     * @param text
129     */
130    void setExtraText(String text);
131
132    /**
133     * Creates subtasks monitor.
134     * @param ticks Number of work units that should be done when subtask finishes
135     * @param internal If true then subtask can't modify task title/custom text
136     */
137    ProgressMonitor createSubTaskMonitor(int ticks, boolean internal);
138
139    /**
140     * Returns the state of user aborts
141     * @return {@code true} if user aborted operation
142     */
143    boolean isCanceled();
144
145    /**
146     * Abort current operation, usually called when user somehow requested an abort
147     */
148    void cancel();
149
150    /**
151     * Add listener for user abort action
152     * @param listener the listener for cancel operation
153     */
154    void addCancelListener(CancelListener listener);
155
156    /**
157     * Remove listener for user abort action
158     * @param listener the listener for cancel operation
159     */
160    void removeCancelListener(CancelListener listener);
161
162    /**
163     * Appends a message to the log managed by the progress monitor.
164     *
165     * @param message the log message. Ignored if null or white space only.
166     */
167    void appendLogMessage(String message);
168
169    /**
170     * Set the task ID of the progress dialog
171     * Should be used only by PleaseWaitRunnable. If taskId {@code <> null} then "In background" button will be shown
172     * @param taskId the task ID
173     */
174    void setProgressTaskId(ProgressTaskId taskId);
175
176    /**
177     * Returns the task ID of the progress dialog
178     * Should be used only by PleaseWaitRunnable
179     * @return the task ID
180     */
181    ProgressTaskId getProgressTaskId();
182
183    /**
184     * Return the parent windows of progress dialog
185     * @return component suitable as parent for dialogs that wants to be shown in front of progress dialog
186     */
187    Component getWindowParent();
188}