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