Package com.bbn.openmap.event

Source Code of com.bbn.openmap.event.ProjectionSupport

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/event/ProjectionSupport.java,v $
// $RCSfile: ProjectionSupport.java,v $
// $Revision: 1.4.2.6 $
// $Date: 2009/02/05 18:45:07 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.event;

import java.util.Iterator;
import java.util.Vector;

import com.bbn.openmap.proj.Projection;

/**
* This is a utility class that can be used by beans that need support for
* handling ProjectionListeners and firing ProjectionEvents. You can use an
* instance of this class as a member field of your bean and delegate work to
* it.
*/
public class ProjectionSupport extends ListenerSupport {

    protected ProjectionChangeNotifier pcNotifier = new ProjectionChangeNotifier();

    /**
     * Construct a ProjectionSupport.
     */
    public ProjectionSupport() {
        this(null);
    }

    /**
     * Construct a ProjectionSupport.
     *
     * @param aSource source Object
     */
    public ProjectionSupport(Object aSource) {
        super(aSource);
        pcNotifier.start();
    }

    /**
     * Add a ProjectionListener.
     *
     * @param l ProjectionListener
     */
    public void addProjectionListener(ProjectionListener l) {
        addListener(l);
    }

    /**
     * Remove a ProjectionListener.
     *
     * @param l ProjectionListener
     */
    public void removeProjectionListener(ProjectionListener l) {
        removeListener(l);
    }

    /**
     * Send a center event to all registered listeners.
     *
     * @param proj Projection
     */
    public void fireProjectionChanged(Projection proj) {
        if (proj == null || size() == 0)
            return; // no event or no listeners

        pcNotifier.fireProjectionEvent(new ProjectionEvent(getSource(), proj));
    }

    public void dispose() {
        pcNotifier.setTerminated(true);
        super.removeAll();
    }

    /**
     * A thread that disperses the projection event, instead of letting the
     * Swing thread do it. A new one is created for every projection change, so
     * the current ProjectionEvent object is getting delivered with it.
     */
    protected class ProjectionChangeNotifier extends Thread {

        private final Object lock = new Object();

        /* current projection event */
        protected ProjectionEvent projEvent;

        /* next projection event */
        protected ProjectionEvent nextEvent;

        /* a flag to know if we are terminated. */
        protected boolean terminated = false;

        public ProjectionChangeNotifier() {}

        public boolean isTerminated() {
            return terminated;
        }

        public void setTerminated(boolean terminated) {
            this.terminated = terminated;
        }

        protected boolean isEventInProgress() {
            // synchronized(lock){
            return projEvent != null;
            // }
        }

        public void fireProjectionEvent(ProjectionEvent event) {
            synchronized (lock) {
                nextEvent = event;
                lock.notifyAll(); // wakes up thread if sleeping
            }
        }

        public void run() {
            Vector lstnrs = null;
            while (!terminated) { // run while parent mapbean exists
                synchronized (lock) {
                    if (nextEvent != null) {
                        projEvent = nextEvent;
                        nextEvent = null;
                    }
                }

                if (projEvent != null && listeners != null) {
                    if (lstnrs == null) {
                        lstnrs = (Vector) listeners.clone();
                    } else {
                        lstnrs.clear();
                    }
                    lstnrs.addAll(listeners);
                    for (Iterator it = lstnrs.iterator(); it.hasNext();) {
                        Object o = it.next();
                        if (nextEvent != null) {
                            break; // new event has been posted, bail out
                        }
                        if (o instanceof ProjectionListener) {
                            ((ProjectionListener) o).projectionChanged(projEvent);
                        }
                    }
                    // notification is complete
                    synchronized (lock) {
                        projEvent = null;
                    }
                } else { // there is no event
                    // just wait until we are awakened for the next event
                    try {
                        synchronized (lock) {
                            lock.wait();
                        }
                    } catch (InterruptedException x) {
                        // do nothing, just reenter loop
                    }
                }
            }
        }
    }

}
TOP

Related Classes of com.bbn.openmap.event.ProjectionSupport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.