📄 backgroundtask.java
字号:
/** * Do part of work of registering the task that must be done before starting * task thread. * The rest of registering work is done in method {@link TaskThread#registerTask}. */ private void registeringTaskWorkBeforeStartingThread() { getRunningTasks().addElement(this); } /** * Waits until starting tasks is enabled. */ private void waitForStartingTasksIsEnabled() { try { synchronized(enableStartingTasksNotifier) { if (enableStartingTasks) return; enableStartingTasksNotifier.wait(); } waitForStartingTasksIsEnabled(); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); } } /** * Waits until starting tasks is enabled. */ private void waitForTerminatingTasksIsEnabled() { try { synchronized(enableTerminatingTasksNotifier) { if (enableTerminatingTasks) return; enableTerminatingTasksNotifier.wait(); } waitForTerminatingTasksIsEnabled(); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); } } /** * Updates progress bar that displays the progress of this task. * * @param actual actual progress * @param total the progress when the task is finished */ public void updateProgress( int total,int actual) { getProgressManager().updateProgress(actual, total); setChanged(); notifyObservers(TaskEvents.UPDATE_PROGRESS); } public void incActual(int increment) { getProgressManager().incActual(increment); setChanged(); notifyObservers(TaskEvents.INC_ACTUAL); } /** * Set the title of the progress bar that displayes the progress of this task. * * @param title the title of the progress bar. */ public void setTitle(String title) { if (DEBUG) { System.out.println("BackgroundTask.setTile(" + title + ")"); } getProgressManager().setTitle(title); setChanged(); notifyObservers(TaskEvents.SET_TITLE); } /** * Sets the text in the alert that will be displayed if the task was minimized * and finishes. * @param alertText */ public void setAlert(String alertText) { this.alertText = alertText; } /** * Set minimum priority to this task. */ void setMinPriority() { thread.setPriority(Thread.MIN_PRIORITY); } /** * In this method it should be specified what the background task will do. */ public abstract void doWork(); /** * Shows progress of the task. If the task is not running, shows next screen. */ public void showProgress() { getProgressManager().showScreen(); } /** * Shows the progress of the task if the task is running. Otherwise do * nothing. */ public void showProgressIfRunning() { if (isRunning()) { showProgress(); } } /** * Gets the screen that should be displayed after task termination. * TODO: this functionality is not needed now. See ProgressManager.ProgressManagerView.paint. * TODO: remove this method if setting next screen while painting progress * of the task that already finished will prove to be working. * @return the nextScreen */ private Displayable getNextScreen() { if (shouldNotDisplayScreen(nextScreen.getScreen())) { ProgressManager.ProgressManagerView nextProgressView = (ProgressManager.ProgressManagerView) nextScreen.getScreen(); return nextProgressView.getTask().getNextScreen(); } return nextScreen.getScreen(); } /** * Returns true if this task is still running. * @return the isRunning true if this task is still running. */ public boolean isRunning() { return isRunning; } /** * Returns true if given screen should not be displayed. * @param screen * @return */ static boolean shouldNotDisplayScreen(Displayable screen) { if (screen instanceof ProgressManager.ProgressManagerView) { return false; // TODO: following version of return leads to race condition!! // It can detect that the task is running. So the task will be // returned by method getNextScreen and its progress possibly setted // as current screen. The problem is than after testing that the // task is running and before setting it as current screen the task // can terminate. Than, the progrogress will be displayed "forewer" // - canceling of displaying the progress is done while terminating // the task // Sollution: a) synchronization: before testing whether the task // is running, some variable signalizing that the task can not // terminate will be setted. Than, ater displaying this task, this // variable will be unseted. // b) does not allow to return progress as next screen: recently // used //return !screenProgressView.getTask().isRunning(); } return false; } /** * @param nextScreen the screen that will be displayd after the termination * of the task. */ void setNextScreen(Displayable nextScreen) { this.nextScreen.setScreen(nextScreen); } /** * Gets progress manager of this task. * @return the progressManager */ ProgressManager getProgressManager() { return progressManager; } /** * The thread in which the task is executed. */ private class TaskThread extends Thread { private final BackgroundTask task; public TaskThread(BackgroundTask task) { this.task = task; } public void run() { registerTask(); if (automaticallyDisplayProgress) { showProgressManager(); } try { doWork(); } catch (RuntimeException rte) { System.err.println("ERROR BackgroundTask.run() unhandled runtime exception:"); rte.printStackTrace(); throw rte; } catch (Error e) { System.err.println("ERROR BackgroundTask.run() unhandled error:"); e.printStackTrace(); throw e; // } catch (Exception e) { // is missing because doWork is not declaring, that it is throwing exceptions... } waitToShowProgress(); if (shouldDisplayNextScreen()) { MujMail.mujmail.getDisplay().setCurrent(nextScreen.getScreen()); //MujMail.mujmail.getDisplay().setCurrent(getNextScreen()); } if (shouldShowAlert()) { showAlert(); } unRegisterTask(); } /** * Registers the task as running. Done while starting task thread. * Note that some registering of task must be done before starting the * thread. See method {@link BackgroundTask#registerTaskWorkBeforeStartingThread} */ private void registerTask() { waitForStartingTasksIsEnabled(); isRunning = true; TasksManager.taskStarted(BackgroundTask.this); } private void unRegisterTask() { waitForTerminatingTasksIsEnabled(); isRunning = false; getRunningTasks().removeElement(task); TasksManager.taskEnded(task); } private boolean shouldDisplayNextScreen() { return isDisplayed(); } private boolean shouldShowAlert() { return !progressManager.stopped() && getProgressManager().minimized() && alertText != null; } private void showAlert() { Alert alert = new Alert(Lang.get(Lang.ALRT_SYS_TASK_FINISHED), alertText, null, AlertType.CONFIRMATION); alert.setTimeout(Alert.FOREVER); MujMail.mujmail.getDisplay().setCurrent(alert,nextScreen.getScreen()); } /** * Shows progress of the task. */ private void showProgressManager() { getProgressManager().showScreen(StartupModes.IN_NEW_THREAD); } /** * If the progress should be displayed, waits until the progress is * displayed. If not, returns immediately. * * This is needed because when the task ends next screen is displayed * using method <code>setCurrent</code>. When the task starts it is * started new thread to display progress screen by using the same * method. It must be ensured that calling <code>setCurrent</code> while * displaying progress bar will be before displaying next screen. */ private void waitToShowProgress() { while (true) { if (automaticallyDisplayProgress && !progressDisplayed) { yield(); //TODO remove this Functions.sleep(100); } else { break; } } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -