/* TaskStatusDialog.java created 2007-10-18 * */ package org.signalml.app.view.common.dialogs; import static org.signalml.app.util.i18n.SvarogI18n._; import static org.signalml.app.util.i18n.SvarogI18n._R; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.AbstractAction; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.KeyStroke; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.signalml.SignalMLOperationMode; import org.signalml.app.action.selector.ActionFocusListener; import org.signalml.app.action.selector.ActionFocusSupport; import org.signalml.app.action.selector.TaskFocusSelector; import org.signalml.app.action.workspace.tasks.AbortTaskAction; import org.signalml.app.action.workspace.tasks.GetTaskErrorAction; import org.signalml.app.action.workspace.tasks.GetTaskResultAction; import org.signalml.app.action.workspace.tasks.ResumeTaskAction; import org.signalml.app.action.workspace.tasks.SuspendTaskAction; import org.signalml.app.method.ApplicationMethodManager; import org.signalml.app.task.ApplicationTaskManager; import org.signalml.app.util.IconUtils; import org.signalml.app.view.common.dialogs.errors.ExceptionDialog; import org.signalml.method.Method; import org.signalml.method.SuspendableMethod; import org.signalml.method.TrackableMethod; import org.signalml.method.iterator.MethodIteratorMethod; import org.signalml.plugin.export.method.SvarogTaskStatusDialog; import org.signalml.task.Task; import org.signalml.task.TaskEvent; import org.signalml.task.TaskEventListener; import org.signalml.task.TaskStatus; /** * Dialog which displays the progress of the {@link Task}. * Contains the label with the status of the task (icon and text) and * the list of progress bars with the progress and the time left. * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class TaskStatusDialog extends JDialog implements TaskEventListener, TaskFocusSelector, SvarogTaskStatusDialog { private static final long serialVersionUID = 1L; /** * the {@link ActionFocusSupport support} to listen for focus changes */ private ActionFocusSupport afSupport = new ActionFocusSupport(this); /** * the boolean which tells if this dialog was initialized */ private boolean initialized = false; /** * the {@link ApplicationTaskManager manager} of {@link Task tasks} */ private ApplicationTaskManager taskManager; /** * the {@link ApplicationMethodManager manager} of {@link Method methods} */ private ApplicationMethodManager methodManager; /** * the {@link Task task} to which this dialog is attached */ private Task task; /** * the {@link CloseAction action} which closes this dialog */ CloseAction closeAction; /** * the {@link AbortTaskAction action} which aborts the task associated * with this dialog */ private AbortTaskAction abortTaskAction; /** * the {@link SuspendTaskAction action} which suspends the task associated * with this dialog */ private SuspendTaskAction suspendTaskAction; /** * the {@link ResumeTaskAction action} which resumes the task associated * with this dialog */ private ResumeTaskAction resumeTaskAction; /** * the {@link GetTaskResultAction action} which shows the result of the * task associated with this dialog */ private GetTaskResultAction getTaskResultAction; /** * the {@link GetTaskErrorAction action} which shows the errors that has * occurred while the task was processed */ private GetTaskErrorAction getTaskErrorAction; /** * the content pane which contains the label with the status of the task * and the progress bars */ private JPanel contentPane; /** * the control pane with 3 buttons: * <ul> * <li>the button which allows to abort a task or get the results * if the task is finished,</li> * <li>the button which allows to close this dialog,</li> * <li>if the task is suspendable - the button which allows to * suspend/resume a task</li> * </ul> */ private JPanel controlPane; /** * the button which {@link CloseAction closes} this dialog */ private JButton closeButton; /** * the button which can be used to {@link AbortTaskAction abort} the task * or show its {@link GetTaskResultAction result} (or * {@link GetTaskErrorAction error} if the error occured) */ private JButton abortAndResultButton; /** * the button which can be used to {@link SuspendTaskAction suspend} or * {@link ResumeTaskAction resume} an action */ private JButton suspendAndResumeButton; /** * boolean which tells if the task can be suspended */ private boolean suspendable = false; /** * boolean which tells if the progress of the task can be tracked */ private boolean trackable = false; /** * the array of booleans - value of index {@code i} tells if the progress * bar of that index shouldn't be trackable */ private boolean[] forceNotTrackable = null; /** * the label with the icon of the current {@link TaskStatus status} */ private JLabel statusIconLabel; /** * the label with the text of the current {@link TaskStatus status} */ private JLabel statusTextLabel; /** * */ private JLabel messageLabel; /** * the number of progress bars */ private int progressCnt; /** * the array or titles of progress bars */ private String[] progressTitles; /** * the array of labels with titles of progress bars */ private JLabel[] progressTitleLabels; /** * the array of labels telling how much time have left until the task * is finished */ private JLabel[] progressETALabels; /** * the array of progress bars */ private JProgressBar[] progressBars; /** * time in miliseconds of the last update of progress bars (at index * {@code i} the time when progress bar of that index was updated) */ private long[] lastETAUpdateMillis; /** * the {@link SignalMLOperationMode mode} in which Svarog is operating */ private SignalMLOperationMode mode; /** * Constructor. Creates this dialog and sets the {@link * SignalMLOperationMode mode} in which Svarog is operating and the * {@link Task task} to which this dialog is attached. * @param task the mode in which Svarog is operating * @param mode the task to which this dialog is attached */ public TaskStatusDialog(Task task, SignalMLOperationMode mode) { super(null, (mode == SignalMLOperationMode.APPLICATION ? Dialog.ModalityType.MODELESS : Dialog.ModalityType.APPLICATION_MODAL)); this.mode = mode; this.task = task; } /** * Initializes this dialog. Performs {@link #initializeInternal()} * exclusively on {@code task}. */ public void initialize() { synchronized (task) { initializeInternal(); } } /** * Initializes this dialog: * <ul> * <li>sets the title and the icon,</li> * <li>creates actions: * <ul><li>{@link AbortTaskAction},</li> * <li>{@link CloseAction},</li> * <li>{@link GetTaskResultAction},</li> * <li>{@link GetTaskErrorAction},</li> * <li>if the method is {@link SuspendableMethod suspendable} - * {@link SuspendTaskAction} and {@link ResumeTaskAction},</li> * </ul></li> * <li>if the method is {@link TrackableMethod trackable} creates the * progress bars,</li> * <li>initializes {@link #initializeContentPane() content pane} and * {@link #initializeControlPane() control pane},</li> * <li>sets that this dialog will be closed when escape is pressed,</li> * <li>adds a window listener, which:<ul> * <li>if the window is closing - removes this dialog from the list of * {@link TaskEventListener task listeners},</li> * <li>if the window is opening: * <ul> * <li>updates the {@link TaskStatus status} of the task,</li> * <li>adds this dialog as the task listener,</li> * </ul></li></ul></li> * <li>sets the current status of the task.</li> * <ul> */ private void initializeInternal() { Method method = task.getMethod(); setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); setTitle(_R("signalml task [{0}]", method.getName())); if (method instanceof MethodIteratorMethod) { setIconImage(IconUtils.loadClassPathImage("org/signalml/app/icon/iteratemethod.png")); } else { setIconImage(IconUtils.loadClassPathImage("org/signalml/app/icon/runmethod.png")); } contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); closeAction = new CloseAction(); abortTaskAction = new AbortTaskAction(this); if (method instanceof SuspendableMethod) { suspendable = true; suspendTaskAction = new SuspendTaskAction(this); resumeTaskAction = new ResumeTaskAction(this); resumeTaskAction.setTaskManager(taskManager); } getTaskResultAction = new GetTaskResultAction(this, new DialogResultListener() { @Override public void dialogCompleted(boolean success) { if (success && closeAction != null) { closeAction.actionPerformed(new ActionEvent(TaskStatusDialog.this, 0, "CLOSE")); } } }); getTaskResultAction.setMethodManager(methodManager); getTaskErrorAction = new GetTaskErrorAction(this); if (method instanceof TrackableMethod) { trackable = true; TrackableMethod trackableMethod = (TrackableMethod) method; progressCnt = trackableMethod.getTickerCount(); progressTitles = new String[progressCnt]; for (int i=0; i<progressCnt; i++) { progressTitles[i] = trackableMethod.getTickerLabel(i); } lastETAUpdateMillis = new long[progressCnt]; } else { progressCnt = 1; progressTitles = new String[1]; progressTitles[0] = _("No detailed progress info"); } initializeControlPane(); initializeContentPane(); getRootPane().setContentPane(contentPane); KeyStroke escape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE"); getRootPane().getActionMap().put("ESCAPE", closeAction); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent arg0) { if (closeAction.isEnabled()) { closeAction.actionPerformed(new ActionEvent(this,0,"close")); taskManager.getEventProxyForTask(task).removeTaskEventListener(TaskStatusDialog.this); } } @Override public void windowOpened(WindowEvent e) { synchronized (task) { TaskStatus taskStatus = task.getStatus(); setStatus(taskStatus); String message = task.getMessage(); if (message != null) { messageLabel.setText(message); } else { messageLabel.setText(""); } taskManager.getEventProxyForTask(task).addTaskEventListener(TaskStatusDialog.this); } } }); pack(); setStatus(task.getStatus()); initialized = true; } @Override public void addActionFocusListener(ActionFocusListener listener) { afSupport.addActionFocusListener(listener); } @Override public void removeActionFocusListener(ActionFocusListener listener) { afSupport.removeActionFocusListener(listener); } /** * Returns the {@link Task task} associated with this dialog. */ @Override public Task getActiveTask() { return task; } /** * Initializes the control pane with 3 buttons: * <ul> * <li>the button which allows to abort a task or get the results * if the task is finished,</li> * <li>the button which allows to close this dialog,</li> * <li>if the task is suspendable - the button which allows to * suspend/resume a task,</li> * </ul> */ protected void initializeControlPane() { controlPane = new JPanel(); controlPane.setLayout(new FlowLayout(FlowLayout.RIGHT,3,3)); if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton = new JButton(suspendTaskAction); controlPane.add(suspendAndResumeButton); } } abortAndResultButton = new JButton(abortTaskAction); controlPane.add(abortAndResultButton); closeButton = new JButton(closeAction); controlPane.add(closeButton); contentPane.add(controlPane,BorderLayout.SOUTH); } /** * Initializes the content pane: * <ul> * <li>sets the sizes and alignments of labels and progress bars,</li> * <li>sets the values of progress bars,</li> * <li>sets the text of labels (including the titles of progress bars). * </li></ul> */ protected void initializeContentPane() { contentPane.setBorder(new EmptyBorder(3,3,3,3)); JComponent interfacePane = new JPanel(); interfacePane.setLayout(new BoxLayout(interfacePane, BoxLayout.Y_AXIS)); interfacePane.setBorder(new TitledBorder(_("Task status"))); int i; Dimension progressSize = new Dimension(350,20); Dimension labelMinSize = new Dimension(progressSize.width, 1); TaskStatus taskStatus = task.getStatus(); statusIconLabel = new JLabel(IconUtils.getLargeTaskIcon(taskStatus)); statusIconLabel.setBorder(new EmptyBorder(0,0,0,5)); Dimension iconRightLabelMinSize = new Dimension(labelMinSize.width-(statusIconLabel.getIcon().getIconWidth()+5), labelMinSize.height); statusTextLabel = new JLabel("sizeinit"); statusTextLabel.setMinimumSize(iconRightLabelMinSize); statusTextLabel.setVerticalTextPosition(JLabel.TOP); statusTextLabel.setAlignmentX(Component.LEFT_ALIGNMENT); Font largeFont = statusTextLabel.getFont().deriveFont(Font.BOLD, 16F); statusTextLabel.setFont(largeFont); messageLabel = new JLabel("sizeinit"); messageLabel.setMinimumSize(new Dimension(iconRightLabelMinSize.width, 10)); messageLabel.setVerticalTextPosition(JLabel.BOTTOM); messageLabel.setAlignmentX(Component.LEFT_ALIGNMENT); Font smallFont = messageLabel.getFont().deriveFont(Font.PLAIN, 10F); messageLabel.setFont(smallFont); progressTitleLabels = new JLabel[progressCnt]; for (i=0; i<progressCnt; i++) { progressTitleLabels[i] = new JLabel(progressTitles[i]); progressTitleLabels[i].setFont(smallFont); progressTitleLabels[i].setAlignmentX(Component.LEFT_ALIGNMENT); } progressBars = new JProgressBar[progressCnt]; if (trackable) { progressETALabels = new JLabel[progressCnt]; for (i=0; i<progressCnt; i++) { progressETALabels[i] = new JLabel("sizeinit"); progressETALabels[i].setFont(smallFont); progressETALabels[i].setMinimumSize(labelMinSize); progressETALabels[i].setAlignmentX(Component.LEFT_ALIGNMENT); progressBars[i] = new JProgressBar(); progressBars[i].setAlignmentX(Component.LEFT_ALIGNMENT); progressBars[i].setPreferredSize(progressSize); progressBars[i].setMinimumSize(progressSize); progressBars[i].setMaximumSize(progressSize); progressBars[i].setStringPainted(true); } } else { progressBars[0] = new JProgressBar(); progressBars[0].setAlignmentX(Component.LEFT_ALIGNMENT); progressBars[0].setPreferredSize(progressSize); progressBars[0].setMinimumSize(progressSize); progressBars[0].setMaximumSize(progressSize); } JPanel labelPanel = new JPanel(new BorderLayout()); labelPanel.setAlignmentX(Component.LEFT_ALIGNMENT); JPanel textLabelPanel = new JPanel(); textLabelPanel.setLayout(new BoxLayout(textLabelPanel, BoxLayout.Y_AXIS)); textLabelPanel.add(statusTextLabel); textLabelPanel.add(messageLabel); labelPanel.add(statusIconLabel, BorderLayout.WEST); labelPanel.add(textLabelPanel, BorderLayout.CENTER); interfacePane.add(labelPanel); interfacePane.add(Box.createVerticalStrut(8)); for (i=0; i<progressCnt; i++) { interfacePane.add(progressTitleLabels[i]); interfacePane.add(Box.createVerticalStrut(1)); interfacePane.add(progressBars[i]); if (trackable) { interfacePane.add(Box.createVerticalStrut(1)); interfacePane.add(progressETALabels[i]); } interfacePane.add(Box.createVerticalStrut(3)); } contentPane.add(interfacePane,BorderLayout.CENTER); } /** * Makes this dialog visible. * If this dialog is not initialized initializes it. * <p>If {@code centered} is set positions this dialog in the center of the * screen. * @param centered {@code true} if this dialog should be positioned in the * center of the screen, {@code false} otherwise */ public final void showDialog(boolean centered) { if (!initialized) { initialize(); initialized = true; } if (centered) { setLocationByPlatform(false); center(); } else { setLocationByPlatform(true); } showDialog(); } /** * Makes this dialog visible. * If this dialog is not initialized initializes it. * Positions the center of this dialog at the specified position. * @param xpos the proportion of width at which the center of this * dialog should be located * @param ypos the proportion of height at which the center of this * dialog should be located */ public final void showDialog(double xpos, double ypos) { if (!initialized) { initialize(); initialized = true; } setLocationByPlatform(false); center(xpos, ypos); showDialog(); } /** * Makes this dialog visible. * If this dialog is not initialized initializes it. */ public final void showDialog() { if (!initialized) { initialize(); initialized = true; } setVisible(true); } /** * Makes this dialog invisible. */ public final void hideDialog() { setVisible(false); } /** * Positions this dialog in the center of the screen. */ public void center() { center(0.5, 0.5); } /** * Changes the location of this dialog. Moves the center of it to the * point in the given proportion of the screen * @param xpos the proportion of width at which the center of this * dialog should be located * @param ypos the proportion of height at which the center of this * dialog should be located */ public void center(double xpos, double ypos) { final double safeXpos = xpos > 1.0 ? 1.0 : (xpos < 0.0 ? 0.0 : xpos); final double safeYpos = ypos > 1.0 ? 1.0 : (ypos < 0.0 ? 0.0 : ypos); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); int x = (int)((d.width - getWidth()) * safeXpos); int y = (int)((d.height - getHeight()) * safeYpos); setLocation(x, y); } /** * Returns the {@link ApplicationTaskManager manager} of {@link Task tasks}. * @return the manager of tasks */ public ApplicationTaskManager getTaskManager() { return taskManager; } /** * Sets the {@link ApplicationTaskManager manager} of {@link Task tasks}. * @param taskManager the manager of tasks */ public void setTaskManager(ApplicationTaskManager taskManager) { this.taskManager = taskManager; } /** * Returns the {@link ApplicationMethodManager manager} of {@link Method * methods}. * @return the manager of methods */ public ApplicationMethodManager getMethodManager() { return methodManager; } /** * Sets the {@link ApplicationMethodManager manager} of {@link Method * methods}. * @param methodManager the manager of methods */ public void setMethodManager(ApplicationMethodManager methodManager) { this.methodManager = methodManager; } /** * Called when the task has been aborted. * Changes the status of progress bars and buttons: * <ul> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value 0,</li> * <li>paints the string on the status bar informing that the task was * aborted.</li></ul> */ @Override public void taskAborted(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Called when the task has been finished. * Changes the status of progress bars and buttons: * <ul> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} * mode changes the state of {@link * #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value maximum (100),</li> * <li>for all progress bars if the bar is trackable and its maximum is * lower then 0 sets both its maximum and value to 1,</li> * <li>paints the string on the status bar informing that the task was * finished,</li></ul> */ @Override public void taskFinished(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Called when the task has been resumed. * Changes the status of progress bars and buttons: * <ul> * <li>changes the state of {@link #abortAndResultButton} to * {@link #abortTaskAction abort},</li> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} * mode and task is suspendable changes the state * of {@link #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * indeterminate and with value maximum,</li> * <li>for all progress bars if the bar is trackable sets its value,</li> * </ul> */ @Override public void taskResumed(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Called when the task has started. * Changes the status of progress bars and buttons: * <ul> * <li>changes the state of {@link #abortAndResultButton} to {@link * #abortTaskAction abort},</li> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode and * task is suspendable changes the state * of {@link #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * indeterminate and with value maximum,</li> * <li>for all progress bars if the bar is trackable sets its value,</li> * </ul> */ @Override public void taskStarted(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Called when the task has been suspended. * Changes the status of progress bars and buttons: * <ul> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} * mode changes the state of {@link * #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value 0,</li> * <li>paints the string on the status bar informing that the task was * suspended,</li></ul> */ @Override public void taskSuspended(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Called when the task request has changed. * Changes the status of progress bars and buttons: * <ul> * <li>changes the state of {@link #abortAndResultButton} to {@link * #abortTaskAction abort},</li> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode and * task is suspendable changes the state * of {@link #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * indeterminate and with value maximum,</li> * <li>for all progress bars if the bar is trackable sets its value,</li> * </ul> */ @Override public void taskRequestChanged(TaskEvent ev) { setStatus(ev.getStatus()); } /** * Sets the text describing the status of the task in the * {@code messageLabel}. * @param ev the event from which message will be obtained */ @Override public void taskMessageSet(TaskEvent ev) { String message = ev.getMessage(); if (message != null) { messageLabel.setText(message); } else { messageLabel.setText(""); } } /** * Updates the values of progress bars with the data from the * {@link TaskEvent task event}. */ @Override public void taskTickerUpdated(TaskEvent ev) { if (trackable) { int[] tickerLimits = ev.getTickerLimits(); int[] tickers = ev.getTickers(); int lastValue; for (int i=0; i<progressCnt; i++) { lastValue = progressBars[i].getValue(); progressBars[i].setMaximum(tickerLimits[i]); progressBars[i].setValue(tickers[i]); updateETA(i,tickerLimits[i],tickers[i],(lastValue<tickers[i])); } } } /** * Calculates the time left until the task finishes and displays it on * the progress bar of a given index. * The update is performed only if at least one second passed since the * last update. * @param index the index of the progress bar * @param limit TODO not used * @param value TODO not used * @param force {@code true} if progress bar should be updated no matter * how many time elapsed */ private void updateETA(int index, int limit, int value, boolean force) { long millis = System.currentTimeMillis(); if (!force && lastETAUpdateMillis[index] != 0 && ((millis-lastETAUpdateMillis[index]) < 1000)) return; lastETAUpdateMillis[index] = millis; final Integer secondsInteger = task.getExpectedSecondsUntilComplete(index); final String _minutes, _seconds; if (secondsInteger == null) { _minutes = _seconds = "--"; } else { _minutes = String.format("%02d", secondsInteger / 60); _seconds = String.format("%02d", secondsInteger % 60); } progressETALabels[index].setText(_R("Expected to end in {0}:{1} min:sec", _minutes, _seconds)); } /** * Using the provided {@link TaskStatus status}: * <ul> * <li>sets which buttons should be enabled depending on the fact if the * task with this status can request the operation associated with the * button,</li> * <li>for status {@link TaskStatus#ABORTED ABORTED}: * <ul> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value 0,</li> * <li>paints the string on the status bar informing that the task was * aborted,</li></ul></li> * <li>for status {@link TaskStatus#SUSPENDED SUSPENDED}: * <ul> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode changes * the state of {@link #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value 0,</li> * <li>paints the string on the status bar informing that the task was * suspended,</li></ul></li> * <li>for status {@link TaskStatus#FINISHED FINISHED}: * <ul> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode changes * the state of {@link #suspendAndResumeButton} to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value maximum (100),</li> * <li>for all progress bars if the bar is trackable and its maximum is * lower then 0 sets both its maximum and value to 1,</li> * <li>paints the string on the status bar informing that the task was * finished,</li></ul></li> * <li>for status {@link TaskStatus#ERROR ERROR}: * <ul> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode changes * the state of {@link #suspendAndResumeButton} to suspend,</li> * <li>changes the state of {@link #abortAndResultButton} to {@link * #getTaskErrorAction error},</li> * <li>for all progress bars if the bar is not trackable sets it as * determinate and with value 0,</li> * <li>paints the string on the status bar informing that the task was * stopped with error,</li></ul></li> * <li>for any other task: * <ul> * <li>changes the state of {@link #abortAndResultButton} to {@link * #abortTaskAction abort},</li> * <li>if Svarog is running in * {@link SignalMLOperationMode#APPLICATION APPLICATION} mode and task * is suspendable changes the state of {@link #suspendAndResumeButton} * to suspend,</li> * <li>for all progress bars if the bar is not trackable sets it as * indeterminate and with value maximum,</li> * <li>for all progress bars if the bar is trackable sets its value,</li> * </ul></li></ul> * @param taskStatus the status of the task */ private void setStatus(TaskStatus taskStatus) { statusIconLabel.setIcon(IconUtils.getLargeTaskIcon(taskStatus)); statusTextLabel.setText(taskStatus.getLongStatus().i18n()); abortTaskAction.setEnabled(taskStatus.isAbortable()); getTaskResultAction.setEnabled(taskStatus.isFinished()); getTaskErrorAction.setEnabled(taskStatus.isError()); if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendTaskAction.setEnabled(taskStatus.isSuspendable()); resumeTaskAction.setEnabled(taskStatus.isResumable()); } } else if (mode == SignalMLOperationMode.APPLET) { closeAction.setEnabled(!taskStatus.isRunning()); } switch (taskStatus) { case ABORTED : if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton.setAction(suspendTaskAction); } } if (trackable) { for (int i=0; i<progressCnt; i++) { if (forceNotTrackable != null && forceNotTrackable[i]) { progressBars[i].setIndeterminate(false); progressBars[i].setMaximum(100); progressBars[i].setValue(0); progressBars[i].setStringPainted(true); progressBars[i].setString(_("Task aborted")); } else { progressETALabels[i].setText(_("Task aborted")); } } } else { progressBars[0].setIndeterminate(false); progressBars[0].setMaximum(100); progressBars[0].setValue(0); progressBars[0].setStringPainted(true); progressBars[0].setString(_("Task aborted")); } break; case SUSPENDED : if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton.setAction(resumeTaskAction); } } if (trackable) { for (int i=0; i<progressCnt; i++) { if (forceNotTrackable != null && forceNotTrackable[i]) { progressBars[i].setIndeterminate(false); progressBars[i].setMaximum(100); progressBars[i].setValue(0); progressBars[i].setStringPainted(true); progressBars[i].setString(_("Task suspended")); } else { progressETALabels[i].setText(_("Task suspended")); } } } else { progressBars[0].setIndeterminate(false); progressBars[0].setMaximum(100); progressBars[0].setValue(0); progressBars[0].setStringPainted(true); progressBars[0].setString(_("Task suspended")); } break; case FINISHED : abortAndResultButton.setAction(getTaskResultAction); if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton.setAction(suspendTaskAction); } } int max; if (trackable) { for (int i=0; i<progressCnt; i++) { if (forceNotTrackable != null && forceNotTrackable[i]) { progressBars[i].setIndeterminate(false); progressBars[i].setMaximum(100); progressBars[i].setValue(100); progressBars[i].setStringPainted(true); progressBars[i].setString(_("Task finished")); } else { progressETALabels[i].setText(_("Task finished")); max = progressBars[i].getMaximum(); if (max <= 0) { progressBars[i].setMaximum(1); progressBars[i].setValue(1); } else { progressBars[i].setValue(max); } } } } else { progressBars[0].setIndeterminate(false); progressBars[0].setMaximum(100); progressBars[0].setValue(100); progressBars[0].setStringPainted(true); progressBars[0].setString(_("Task finished")); } break; case ERROR : abortAndResultButton.setAction(getTaskErrorAction); if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton.setAction(suspendTaskAction); } } if (trackable) { for (int i=0; i<progressCnt; i++) { if (forceNotTrackable != null && forceNotTrackable[i]) { progressBars[i].setIndeterminate(false); progressBars[i].setMaximum(100); progressBars[i].setValue(0); progressBars[i].setStringPainted(true); progressBars[i].setString(_("Task finished")); } else { progressETALabels[i].setText(_("Task finished")); } } } else { progressBars[0].setIndeterminate(false); progressBars[0].setMaximum(100); progressBars[0].setValue(0); progressBars[0].setStringPainted(true); progressBars[0].setString(_("Task finished")); } break; default : abortAndResultButton.setAction(abortTaskAction); if (mode == SignalMLOperationMode.APPLICATION) { if (suspendable) { suspendAndResumeButton.setAction(suspendTaskAction); } } if (trackable) { int[] tickerLimits; int[] tickers; synchronized (task) { tickerLimits = task.getTickerLimits(); tickers = task.getTickers(); } for (int i=0; i<progressCnt; i++) { if (forceNotTrackable != null && forceNotTrackable[i]) { progressBars[i].setIndeterminate(true); progressBars[i].setMaximum(100); progressBars[i].setValue(0); progressBars[i].setStringPainted(false); } else { updateETA(i,tickerLimits[i],tickers[i],true); } } } else { progressBars[0].setIndeterminate(true); progressBars[0].setMaximum(100); progressBars[0].setValue(0); progressBars[0].setStringPainted(false); } } } /** * Action which hides {@link TaskStatusDialog this dialog}. * If Svarog is running in {@link SignalMLOperationMode#APPLET applet} mode * also removes the task associated with this dialog. */ protected class CloseAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the description. */ public CloseAction() { super(_("Close")); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/close.png")); } /** * When this action is performed hides {@link TaskStatusDialog this * dialog} and f Svarog is running in {@link SignalMLOperationMode#APPLET * applet} mode also removes the task associated with this dialog. */ public void actionPerformed(ActionEvent arg0) { hideDialog(); if (mode == SignalMLOperationMode.APPLET) { taskManager.removeTask(task); } } } }