    001    // This file is part of the Attempto Java Packages.
    002    // Copyright 2008, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
    003    //
    004    // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the
    005    // terms of the GNU Lesser General Public License as published by the Free Software Foundation,
    006    // either version 3 of the License, or (at your option) any later version.
    007    //
    008    // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY
    009    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    010    // PURPOSE. See the GNU Lesser General Public License for more details.
    011    //
    012    // You should have received a copy of the GNU Lesser General Public License along with the Attempto
    013    // Java Packages. If not, see http://www.gnu.org/licenses/.
    014
    015    package ch.uzh.ifi.attempto.echocomp;
    016
    017    import java.util.HashMap;
    018
    019    import nextapp.echo2.app.ApplicationInstance;
    020    import nextapp.echo2.app.Column;
    021    import nextapp.echo2.app.Component;
    022    import nextapp.echo2.app.TaskQueueHandle;
    023
    024    /**
    025     * This abstract class can be used to create components that are initialized asynchronously in the background.
    026     * This is makes sense for components that require some time to create themselves (e.g. because of time
    027     * expensive calculations).
    028     *
    029     * @author Tobias Kuhn
    030     */
    031    public abstract class DelayedComponent extends Column {
    032
    033            private static HashMap<ApplicationInstance, TaskQueueHandle> taskQueues = new HashMap<ApplicationInstance, TaskQueueHandle>();
    034
    035            /**
    036             * Creates a new delayed component which shows the temporary component until the real component is
    037             * ready.
    038             *
    039             * @param tempComponent The temporary component.
    040             */
    041            public DelayedComponent(Component tempComponent) {
    042                    if (tempComponent != null) {
    043                            add(tempComponent);
    044                    }
    045
    046                    final ApplicationInstance application = ApplicationInstance.getActive();
    047                    TaskQueueHandle taskQueueTemp = taskQueues.get(application);
    048                    if (taskQueueTemp == null) {
    049                            taskQueueTemp = application.createTaskQueue();
    050                            taskQueues.put(application, taskQueueTemp);
    051                    }
    052                    final TaskQueueHandle taskQueue = taskQueueTemp;
    053
    054                    Thread thread = new Thread() {
    055                            public synchronized void run() {
    056                                    final Component c = initComponent();
    057                                    application.enqueueTask(
    058                                            taskQueue,
    059                                            new Runnable() {
    060                                                    public synchronized void run() {
    061                                                            DelayedComponent.this.removeAll();
    062                                                            DelayedComponent.this.add(c);
    063                                                    }
    064                                            }
    065                                    );
    066                            }
    067                    };
    068
    069                    thread.start();
    070            }
    071
    072
    073            /**
    074             * Creates a new delayed component with no temporary component.
    075             */
    076            public DelayedComponent() {
    077                    this(null);
    078            }
    079
    080            /**
    081             * This method should contain the (possibly time-consuming) operations to create the actual GUI
    082             * component. This operation will be performed asynchronously. As soon as it is finished, the
    083             * temporary component (if present) is replaced by the component this method returns.
    084             *
    085             * @return The GUI component.
    086             */
    087            public abstract Component initComponent();
    088
    089    }