All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.swm.commons.mobile.client.widgets.progressbar.MobileProgressBar Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2011 SWM Services GmbH.
 * 
 * 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 de.swm.commons.mobile.client.widgets.progressbar;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.InvocationException;
import de.swm.commons.mobile.client.widgets.LoadingIndicatorPopup;
import de.swm.gwt.client.progressbar.IProgressBarNoCancelWaitDialog;

import java.util.ArrayList;
import java.util.List;



/**
 * Progress bar for mobile applications.
 * 
 */
public class MobileProgressBar implements IProgressBarNoCancelWaitDialog {

	private final List callbacksToCancel = new ArrayList();
	private final List runAsyncCallbacks = new ArrayList();
	private final List> asyncCallbacks = new ArrayList>();
	private boolean isStopped;
	private final LoadingIndicatorPopup loadingPanel;



	/**
	 * Default constructor.
	 */
	public MobileProgressBar() {
		isStopped = true;
		this.loadingPanel = new LoadingIndicatorPopup();
	}
	
	/**
	 * Constructor with possibility to enable info text.
	 * 
	 * @param showInfoText whether an info text should be shown inside the loading indicator popup
	 */
	public MobileProgressBar(boolean showInfoText) {
		isStopped = true;
		this.loadingPanel = new LoadingIndicatorPopup(showInfoText);
	}

	/**
	 * Sets the information text that is shown inside the loading indicator popup.
	 * 
	 * @param loadingText
	 */
	public void setLoadingText(String loadingText) {
		this.loadingPanel.setLoadingText(loadingText);
	}
	
	/**
	 * Sets the subtitle that is shown inside the loading indicator popup.
	 * 
	 * @param loadingSubtitleText
	 */
	public void setLoadingSubtitleText(String loadingSubtitleText) {
		this.loadingPanel.setLoadingSubtitleText(loadingSubtitleText);
	}

	/**
	 * Sets the loading indicator image inside the loading indicator popup.
	 * @param imageResource
	 */
	public void setLoadingImage(ImageResource imageResource) {
		this.loadingPanel.setLoadingImage(imageResource);
	}

	/**
	 * Zeigt den Wartebalken an.
	 * 
	 * 
	 */
	public void showDialog() {
		loadingPanel.showCentered(true);
	}



	/**
	 * {@inheritDoc}
	 * 
	 * @see de.swm.issng.gkpk.client.utils.progressbar.IProgressBarWaitDialog#start()
	 */
	@Override
	public  AsyncCallback start(final AsyncCallback callbackToExecute) {
		if (isStopped || !this.loadingPanel.isVisible()) {
			showDialog();
		}
		isStopped = false;
		final CancelMonitor monitor = new CancelMonitor();
		AsyncCallback wrappedCallback = new AsyncCallback() {

			@Override
			public void onFailure(Throwable error) {
				if (!monitor.isCanceled()) {
					callbackToExecute.onFailure(error);
				}
				removeFromQueue(this);
				// Falls es sich um eine Unchecked Exception auf dem Server handelt
				// oder falls ein anderer unerwarteter Fehler auftritt (Netzwerk etc)
				// oder falls der RemoteService nicht kompatibel ist
				// werden alle Callbacks abgebrochen und der Dialog geschlossen.
				if (error instanceof InvocationException || error instanceof IncompatibleRemoteServiceException) {
					cancelCallbacksAndForceStop();
				}
			}



			@Override
			public void onSuccess(T success) {
				if (!monitor.isCanceled()) {
					callbackToExecute.onSuccess(success);
				}
				removeFromQueue(this);
			}

		};
		callbacksToCancel.add(monitor);
		asyncCallbacks.add(wrappedCallback);
		return wrappedCallback;
	}



	/**
	 * {@inheritDoc}
	 * 
	 * @see de.swm.issng.gkpk.client.utils.progressbar.IProgressBarWaitDialog#start()
	 */
	@Override
	public void start(final RunAsyncCallback callbackToExecute) {

		if (isStopped || !this.loadingPanel.isVisible()) {
			showDialog();
		}
		isStopped = false;
		final CancelMonitor monitor = new CancelMonitor();
		RunAsyncCallback wrappedCallback = new RunAsyncCallback() {

			@Override
			public void onFailure(Throwable error) {
				if (!monitor.isCanceled()) {
					callbackToExecute.onFailure(error);
				}
				cancelCallbacksAndForceStop();
			}



			@Override
			public void onSuccess() {
				if (!monitor.isCanceled()) {
					callbackToExecute.onSuccess();
				}
				removeFromQueue(this);
			}

		};

		callbacksToCancel.add(monitor);
		runAsyncCallbacks.add(wrappedCallback);
		GWT.runAsync(wrappedCallback);
	}



	/**
	 * Canceled alles und entfernt alle wartenden callbacks.
	 */
	private void cancelCallbacksAndForceStop() {
		this.runAsyncCallbacks.clear();
		this.asyncCallbacks.clear();
		for (CancelMonitor toCancel : callbacksToCancel) {
			toCancel.setCanceled(true);
		}
		this.callbacksToCancel.clear();
		isStopped = true;

		this.loadingPanel.setVisible(false);
	}



	/**
	 * Entfernt den callback und canceled den Dialog, wenn es die letzte Aktion ist.
	 * 
	 * @param toRemove
	 *            der callbck der zu entfernen ist.
	 */
	private void removeFromQueue(RunAsyncCallback toRemove) {
		this.runAsyncCallbacks.remove(toRemove);
		if (asyncCallbacks.isEmpty() && runAsyncCallbacks.isEmpty()) {
			cancelCallbacksAndForceStop();
		}
	}



	/**
	 * Entfernt den callback und canceled den Dialog, wenn es die letzte Aktion ist.
	 * 
	 * @param toRemove
	 *            der callbck der zu entfernen ist.
	 */
	private void removeFromQueue(AsyncCallback toRemove) {
		this.asyncCallbacks.remove(toRemove);
		if (asyncCallbacks.isEmpty() && runAsyncCallbacks.isEmpty()) {
			cancelCallbacksAndForceStop();
		}
	}

	/**
	 * Hilfsklasse um einen laufenden callback zu canceln.
	 * 
	 * @author Wiese.Daniel 
* copyright (C) 2010-2011, SWM Services GmbH * */ public static class CancelMonitor { private boolean canceled = false; public boolean isCanceled() { return canceled; } public void setCanceled(boolean canceled) { this.canceled = canceled; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy