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