omgraphichandlerlayer.java

来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 1,519 行 · 第 1/4 页

JAVA
1,519
字号
// **********************************************************************
// 
// <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/layer/OMGraphicHandlerLayer.java,v $
// $RCSfile: OMGraphicHandlerLayer.java,v $
// $Revision: 1.18.2.15 $
// $Date: 2007/04/24 19:55:45 $
// $Author: dietrick $
// 
// **********************************************************************

package com.bbn.openmap.layer;

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Shape;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.bbn.openmap.Layer;
import com.bbn.openmap.PropertyConsumer;
import com.bbn.openmap.event.InfoDisplayEvent;
import com.bbn.openmap.event.LayerStatusEvent;
import com.bbn.openmap.event.MapMouseEvent;
import com.bbn.openmap.event.MapMouseListener;
import com.bbn.openmap.event.ProjectionEvent;
import com.bbn.openmap.layer.policy.ProjectionChangePolicy;
import com.bbn.openmap.layer.policy.RenderPolicy;
import com.bbn.openmap.layer.policy.StandardPCPolicy;
import com.bbn.openmap.layer.policy.StandardRenderPolicy;
import com.bbn.openmap.omGraphics.FilterSupport;
import com.bbn.openmap.omGraphics.OMAction;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.omGraphics.event.GestureResponsePolicy;
import com.bbn.openmap.omGraphics.event.MapMouseInterpreter;
import com.bbn.openmap.omGraphics.event.StandardMapMouseInterpreter;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.ComponentFactory;
import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.PaletteHelper;
import com.bbn.openmap.util.PropUtils;
import com.bbn.openmap.util.SwingWorker;

/**
 * The OMGraphicHandlerLayer is a layer that provides OMGraphicHandler support.
 * With this support, the OMGraphicHandlerLayer can accept OMAction instructions
 * for managing OMGraphics, and can perform display filtering as supported by
 * the FilterSupport object.
 * <P>
 * 
 * When extending this class for a simple layer, they only method you need to
 * override is the prepare() method. This is a good class to use to start
 * writing your own layers. Start with overriding the prepare() method, having
 * it return an OMGraphicList containing OMGraphics on the map that are
 * appropriate for the current projection.
 * <P>
 * 
 * The OMGraphicHandlerLayer already has an OMGraphicList variable, so if you
 * extend this class you don't have to manage another one. You can add your
 * OMGraphics to the list provided with getList(). If you create a list of
 * OMGraphics that is reused and simply re-projected when the projection
 * changes, do nothing - that's what happens anyway based on the default
 * ProjectionChangePolicy set for the layer (StandardPCPolicy). You can either
 * create an OMGraphicList in the constructor and set it by calling
 * setList(OMGraphicList), or you can test for a null OMGraphicList returned
 * from getList() in prepare() and create one if it needs to be. If the list
 * isn't null, make sure you still call generate on it. The advantage of waiting
 * to create the list in prepare is that the processing time to create the
 * OMGraphics is delayed until the layer is added to the map. If you create
 * OMGraphics in the constructor, you delay the entire program (maybe startup of
 * the map!) while the OMGraphics are created.
 * <P>
 * 
 * If you let prepare() create a new OMGraphicList based on the new projection,
 * then make sure the ProjectionChangePolicy for the layer is set to a
 * com.bbn.openmap.layer.policy.ResetListPCPolicy, or at least clear out the old
 * graphics at some point before adding new OMGraphics to the list in that
 * method. You just have to do one, not both, of those things. If you are
 * managing a lot of OMGraphics and do not null out the list, you may see your
 * layer appear to lag behind the projection changes. That's because another
 * layer with less work to do finishes and calls repaint, and since your list is
 * still set with OMGraphics ready for the old projection, it will just draw
 * what it had, and then draw again when it has finished working. Nulling out
 * the list will prevent your layer from drawing anything on the new projection
 * until it is ready.
 * <P>
 * 
 * The OMGraphicHandlerLayer has support built in for launching a SwingWorker to
 * do work for you in a separate thread. This behavior is controlled by the
 * ProjectionChangePolicy that is set for the layer. Both the StandardPCPolicy
 * and ListResetPCPolicy launch threads by calling doPrepare() on this layer.
 * The StandardPCPolicy only calls this if the number of OMGraphics on its list
 * is greater than some cutoff value.
 * <P>
 * 
 * useLayerWorker variable is true (default), then doPrepare() will be called
 * when a new ProjectionEvent is received in the projectionChanged method. This
 * will cause prepare() to be called in a separate thread. You can use prepare()
 * to create OMGraphics, the projection will have been set in the layer and is
 * available via getProjection(). You should generate() the OMGraphics in
 * prepare. NOTE: You can override the projectionChanged() method to
 * create/manage OMGraphics any way you want. The SwingWorker only gets launched
 * if doPrepare() gets called.
 * <P>
 * 
 * MouseEvents are not handled by a MapMouseInterpreter, with the layer being
 * the GestureResponsePolicy object dictating how events are responded to. The
 * interpreter does the work of fielding MapMouseEvents, figuring out if they
 * concern an OMGraphic, and asking the policy what it should do in certain
 * situations, including providing tooltips, information, or opportunities to
 * edit OMGraphics. The mouseModes property can be set to the MapMouseMode IDs
 * that the interpreter should respond to.
 * <P>
 * 
 * For OMGraphicHandlerLayers, there are several properties that can be set that
 * dictate important behavior:
 * 
 * <pre>
 *   
 *    
 *    
 *     layer.projectionChangePolicy=pcp
 *     layer.pcp.class=com.bbn.openmap.layer.policy.StandardPCPolicy
 *    
 *     layer.renderPolicy=srp
 *     layer.srp.class=com.bbn.openmap.layer.policy.StandardRenderPolicy
 *     # or
 *     layer.renderPolicy=ta
 *     layer.ta.class=com.bbn.openmap.layer.policy.RenderingHintsRenderPolicy
 *     layer.ta.renderingHints=KEY_TEXT_ANTIALIASING
 *     layer.ta.KEY_TEXT_ANTIALIASING=VALUE_TEXT_ANTIALIAS_ON
 *    
 *     layer.mouseModes=Gestures
 *     layer.consumeEvents=true
 *     
 *    
 * </pre>
 */
public class OMGraphicHandlerLayer extends Layer implements
        GestureResponsePolicy {

    /**
     * The property that can be set for the ProjectionChangePolicy. This
     * property should be set with a scoping marker name used to define a policy
     * class and any other properties that the policy should use.
     * "projectionChangePolicy"
     * 
     * @see com.bbn.openmap.layer.policy.ProjectionChangePolicy
     * @see com.bbn.openmap.layer.policy.StandardPCPolicy
     * @see com.bbn.openmap.layer.policy.ListResetPCPolicy
     */
    public final static String ProjectionChangePolicyProperty = "projectionChangePolicy";
    /**
     * The property that can be set for the RenderPolicy. This property should
     * be set with a marker name used to define a policy class and any other
     * properties that the policy should use. "renderPolicy"
     * 
     * @see com.bbn.openmap.layer.policy.StandardRenderPolicy
     * @see com.bbn.openmap.layer.policy.BufferedImageRenderPolicy
     * @see com.bbn.openmap.layer.policy.RenderingHintsRenderPolicy
     */
    public final static String RenderPolicyProperty = "renderPolicy";

    /**
     * The property that can be set to tell the layer which mouse modes to
     * listen to. The property should be a space-separated list of mouse mode
     * IDs, which can be specified for a MapMouseMode in the properties file or,
     * if none is specified, the default ID hard-coded into the MapMouseMode.
     * "mouseModes"
     */
    public final static String MouseModesProperty = "mouseModes";

    /**
     * The property that can be set to tell the layer to consume mouse events.
     * The maim reason not to do this is in case you have OMGraphics that you
     * are moving, and you need other layers to respond to let you know when you
     * are over the place you think you need to be.
     */
    public final static String ConsumeEventsProperty = "consumeEvents";

    /**
     * The property to tell the layer how transparent it is. 0 is totally clear,
     * 1f is opaque.
     */
    public final static String TransparencyProperty = "transparency";
    /**
     * The property to tell the layer if the thread launched for prepare()
     * method calls can be interrupted. If false, the thread will be allowed to
     * complete it's work. This (false) is generally a good setting for layers
     * contacting servers. The default setting is, however, true.
     */
    public final static String InterruptableProperty = "interruptable";

    /**
     * Filter support that can be used to manage OMGraphics.
     */
    protected FilterSupport filter = new FilterSupport();

    /**
     * The ProjectionChangePolicy object that determines how a layer reacts and
     * sets up the OMGraphicList to be rendered for the layer when the
     * projection changes.
     */
    protected ProjectionChangePolicy projectionChangePolicy = null;

    /**
     * The RenderPolicy object that determines how a layer's OMGraphicList is
     * rendered in the layer.paint() method.
     */
    protected RenderPolicy renderPolicy = null;

    /**
     * A SwingWorker that can be used for gathering OMGraphics or doing other
     * work in a different thread.
     */
    protected SwingWorker layerWorker;

    protected String[] mouseModeIDs = null;

    /**
     * A flag to tell the layer to be selfish about consuming MouseEvents it
     * receives. If set to true, it will consume events so that other layers
     * will not receive the events. If false, lower layers will also receive
     * events, which will let them react too. Intended to let other layers
     * provide information about what the mouse is over when editing is
     * occuring.
     */
    protected boolean consumeEvents = false;

    /**
     * Flag used to avoid the SwingWorker to be interrupted. Usefull for layers
     * that load an image from a server such as the WMSPlugin to avoid an ugly
     * java output "Interrupted while loading image".
     */
    protected boolean interruptable = true;

    /**
     * Sets the interruptable flag
     */
    public void setInterruptable(boolean b) {
        interruptable = b;
    }

    /**
     * Queries for the interruptable flag.
     * 
     * @return
     */
    public boolean isInterruptable() {
        return interruptable;
    }

    // OMGraphicHandler methods, deferred to FilterSupport...

    /**
     * Sets all the OMGraphics outside of this shape to be invisible. Also
     * returns another OMGraphicList containing OMGraphics that are contained
     * within the Shape provided.
     */
    public OMGraphicList filter(Shape withinThisShape) {
        return filter.filter(withinThisShape);
    }

    /**
     * @see com.bbn.openmap.omGraphics.OMGraphicHandler#filter(Shape, boolean).
     */
    public OMGraphicList filter(Shape shapeBoundary, boolean getInsideBoundary) {
        return filter.filter(shapeBoundary, getInsideBoundary);
    }

    /**
     * To find out whether SQL queries are handled.
     * 
     * @see com.bbn.openmap.omGraphics.OMGraphicHandler#supportsSQL().
     */
    public boolean supportsSQL() {
        return filter.supportsSQL();
    }

    /**
     * Depending on the filter's SQL support, returns an OMGraphicList that fit
     * the query.
     */
    public OMGraphicList filter(String SQLQuery) {
        return filter.filter(SQLQuery);
    }

    /**
     * Perform the OMAction on the OMGraphic, within the OMGraphicList contained
     * in the layer.
     */
    public boolean doAction(OMGraphic graphic, OMAction action) {
        return filter.doAction(graphic, action);
    }

    /**
     * Get the OMGraphicList held by the layer. May be null.
     */
    public OMGraphicList getList() {
        return filter.getList();
    }

    /**
     * Indicates if the OMGraphicHandler can have its OMGraphicList set.
     */
    public boolean canSetList() {
        return filter.canSetList();
    }

    /**
     * Set the OMGraphicList within this OMGraphicHandler. Works if
     * canSetGraphicList == true.
     */
    public void setList(OMGraphicList omgl) {
        filter.setList(omgl);
    }

    /**
     * Remove all filters, and reset all graphics to be visible.
     */
    public void resetFiltering() {
        filter.resetFiltering();
    }

    /**
     * Don't set to null. This is here to let subclasses put a more/less capable
     * FilterSupport in place.
     */
    public void setFilter(FilterSupport fs) {
        filter = fs;
    }

    /**
     * Get the FilterSupport object that is handling the OMGraphicHandler
     * methods.
     */
    public FilterSupport getFilter() {
        return filter;
    }

    /**
     * From the ProjectionListener interface. The method gets called when the
     * layer is part of the map, and whenever the map projection changes. Will
     * trigger a repaint().
     * <p>
     * 
     * The ProjectionEvent is passed to the current ProjectionChangePolicy
     * object, which determines what will happen on the layer and how. By
     * default, a StandardPCPolicy is notified with the projection change, and
     * it will test the projection for changes and make sure prepare() is
     * called. It will make the decision whether doPrepare() is called, based on
     * the number of OMGraphics on the list, which may launch a swing worker
     * thread to call prepare(). The StandardPCPolicy does not do anything to
     * the OMGraphicList when the projection changes.
     * <p>
     * 
     * If you need the OMGraphicList cleared out with a new projection, you can
     * substitute a ListRestPCPolicy for the StandardPCPolicy. You would want to
     * do this if your OMGraphicList changes for different projections - The

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?