net.sf.sfac.gui.asynch.AsynchStatusProviderImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sfac-core Show documentation
Show all versions of sfac-core Show documentation
This project is the core part of the Swing Framework and Components (SFaC).
It contains the Swing framework classes and the graphical component classes.
The newest version!
/*-------------------------------------------------------------------------
Copyright 2009 Olivier Berlanger
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------------*/
package net.sf.sfac.gui.asynch;
import java.awt.Component;
import net.sf.sfac.lang.LanguageSupport;
import net.sf.sfac.lang.MultiLingualException;
import net.sf.sfac.setting.Settings;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Base implementation of AsynchStatusProvider.
* Subclasses have just to implement the method:
*
*
* public void doExecute(Component parent, Object parameters)
*
*
* to implement the the actual asynchrone task.
* To enhance the task progress reporting (in the AsynchStatusDialog) you can either:
*
* Call the setActionMessage() from your task execution to change the message displayed in the GUI.
* or
* Override the two following methods:
*
* public int getStatusLineCount()
: return the number of status line (default is 2).
* public String getStatusLine(int index)
: return the current value of each status line. In the implementation of
* this method you can rely on the 'super' implementation to provide 1 or 2 relevant lines of message in all the cases (based on the
* actionMessage).
*
* Then when the execute(Component parent, Object parameters) method is called, this object does the following:
*
* - Call the
beforeAction(Component)
method (empty by default)
* - Start a new thread to call the doExecute(Component parent, Object parameters) method (and catch any exception)
*
- Create a AsynchStatusDialog and show it to display the execution status (with a refresh timer).
*
- Call the
afterAction(Component)
method (empty by default)
*
* Note that the beforeAction(Component)
and afterAction(Component)
methods are called on the
* event-dispatch thread. So they can be used to display custom dialog (confirmation, display results ...).
* The behaviour of the dialog can be modified by overriding the following methods:
*
* displayCancelButton()
: if return false, no "Cancel" button is displayed (true by default).
* displayOkButton()
: if return false, no "Ok" button is displayed (true by default).
* displayProgressBar()
: if return true, a progress bar is displayed (false by default). If a progressBar is
* displayed, the getPercentComplete() method must be implemented.
*
* Note: to dispose the status dialog (without the user having to click on a button) when job is done, you can set the actions
* status to ActionStatus.TO_DISPOSE.
*
* @author Olivier Berlanger
*/
public abstract class AsynchStatusProviderImpl implements AsynchStatusProvider {
private static Log log = LogFactory.getLog(AsynchStatusProviderImpl.class);
private Settings setts;
private ActionStatus actionStatus;
private String actionMessage;
private AsynchStatusDialog statusDialog;
private int dotCount;
public AsynchStatusProviderImpl(Settings settngs) {
setts = settngs;
}
public void setStatus(ActionStatus newStatus) {
actionStatus = newStatus;
}
public String getActionMessage() {
return actionMessage;
}
public void setActionMessage(String newActionMessage) {
actionMessage = newActionMessage;
}
public Settings getSettings() {
return setts;
}
protected void berforeAction(Component parent) {
}
protected void afterAction(Component parent) {
}
protected abstract void doExecute(Component parent, Object parameters) throws Exception;
public void execute(final Component parent, final Object parameters) throws Exception {
actionStatus = ActionStatus.RUNNING;
final String defaultStartMessage = LanguageSupport.getOptionalLocalizedString("starting_action", "Starting ...");
final String defaultRunMessage = LanguageSupport.getOptionalLocalizedString("running_action", "Running ...");
actionMessage = defaultStartMessage;
dotCount = 0;
berforeAction(parent);
if (actionStatus == ActionStatus.RUNNING) {
// start import thread
new Thread("AsynchroneAction") {
@Override
public void run() {
if (defaultStartMessage.equals(getActionMessage())) {
setActionMessage(defaultRunMessage);
}
doExecuteProtected(parent, parameters);
if (defaultRunMessage.equals(getActionMessage())) {
setActionMessage(LanguageSupport.getOptionalLocalizedString("action_done", "Done."));
}
}
}.start();
showStatusDialog(parent);
afterAction(parent);
}
}
protected void doExecuteProtected(Component parent, Object parameters) {
try {
// Wait for the status dialog to be displayed.
// If we do not do that and the process directly displays another modal dialog (with status dialog as parent),
// then the child dialog is displayed before its parent (owner) and the incorrect dialog receives focus.
while ((statusDialog == null) || (!statusDialog.isVisible())) {
Thread.sleep(50);
}
doExecute(parent, parameters);
if (getStatus() == ActionStatus.RUNNING) setStatus(ActionStatus.DONE);
} catch (UserAbortException uae) {
log.warn(getClass().getSimpleName() + " action aborted by user");
actionMessage = "Aborted";
actionStatus = ActionStatus.ABORTED;
} catch (MultiLingualException mle) {
log.error(getClass().getSimpleName() + " action failure", mle);
actionMessage = mle.getText(LanguageSupport.getCurrentLocale());
actionStatus = ActionStatus.FAILED;
} catch (Exception e) {
log.error(getClass().getSimpleName() + " action failure", e);
actionMessage = e.getClass().getSimpleName() + ": " + e.getMessage();
actionStatus = ActionStatus.FAILED;
}
}
protected void showStatusDialog(Component parent) {
// show status dialog
statusDialog = new AsynchStatusDialog(parent, this, setts);
if (log.isDebugEnabled()) log.debug("Create status dialog: " + statusDialog);
statusDialog.startUpdates();
statusDialog.setVisible(true);
}
protected void disposeStatusDialog() {
if (log.isDebugEnabled()) log.debug("Dispose status dialog: " + statusDialog);
if (statusDialog != null) {
statusDialog.dispose();
statusDialog = null;
}
}
// --------------------- AsynchStatusProvider interface implementation ------------------------------------------
public void cancelAction() {
if (actionStatus == ActionStatus.RUNNING) actionStatus = ActionStatus.ABORTED;
else actionStatus = ActionStatus.TO_DISPOSE;
}
public void okAction() {
actionStatus = ActionStatus.TO_DISPOSE;
}
public boolean displayOkButton() {
return true;
}
public boolean displayCancelButton() {
return true;
}
public boolean isCancelAllowed() {
return actionStatus == ActionStatus.RUNNING;
}
public String getProviderId() {
return getClass().getSimpleName();
}
public ActionStatus getStatus() {
return actionStatus;
}
public boolean hasStatusLineChanged(int newIndex) {
return true;
}
public boolean displayProgressBar() {
return false;
}
public int getPercentComplete() {
return 0;
}
public String getStatusLine(int index) {
switch (getStatus()) {
case FAILED:
if (index == 0) return "Action failed!";
if (index == 1) return getActionMessage();
return "";
case ABORTED:
if (index == 0) return "Action aborted";
if (index == 1) return "by user!";
return "";
case RUNNING:
if (index == 0) return getActionMessage();
if (index == 1) return getDottedLine();
return "";
case DONE:
if (index == 0) return getActionMessage();
return "";
case TO_DISPOSE:
return "";
}
throw new IllegalStateException("Unknown status: " + getStatus());
}
private String getDottedLine() {
dotCount = (dotCount % 16) + 1;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dotCount; i++) {
sb.append('.');
}
return sb.toString();
}
public int getStatusLineCount() {
return 2;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy