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    }