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

nl.cloudfarming.client.geoviewer.jxmap.map.MapWidgetFactory Maven / Gradle / Ivy

Go to download

AgroSense geoviewer JXMap implementation. Contains a map/geoviewer TopComponent based on the JXMap classes from swingx.

The newest version!
/**
 * Copyright (C) 2008-2012 AgroSense Foundation.
 *
 * AgroSense is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
 * this software, see the FLOSS License Exception
 * .
 *
 * AgroSense is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with AgroSense.  If not, see .
 */
package nl.cloudfarming.client.geoviewer.jxmap.map;

import java.awt.Point;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import javax.swing.Action;
import javax.swing.JPopupMenu;
import nl.cloudfarming.client.geoviewer.*;
import nl.cloudfarming.client.geoviewer.jxmap.MapProperties;
import nl.cloudfarming.client.geoviewer.jxmap.render.JXMapGeoTranslator;
import nl.cloudfarming.client.geoviewer.render.GeoTranslator;
import nl.cloudfarming.client.geoviewer.render.GeometricalWidget;
import nl.cloudfarming.client.geoviewer.render.GridCoverage2DWidget;
import nl.cloudfarming.client.geoviewer.render.IconWidget;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.PopupMenuProvider;
import org.netbeans.api.visual.widget.Widget;
import org.openide.nodes.Node;
import org.openide.util.Utilities;

/**
 * factory class for the creation of map widgets
 *
 *
 * @author Timon Veenstra
 */
public class MapWidgetFactory {

    private static final Logger LOGGER = Logger.getLogger("nl.cloudfarming.client.geoviewer.jxmap.map.MapWidgetFactory");

    /**
     * Create a widget from a node and a scene
     *
     * @param node node to create a widgets for
     * @param scene scene to create the widget on
     * @return the created widget
     */
    static Widget createWidgetFromNode(final Node node, MapScene scene) {
        Geometrical geometrical = node.getLookup().lookup(Geometrical.class);
        Layer layer = Layer.Finder.findLayer(node);
        Palette palette = getPalette(node, layer);


        if (layer == null) {
            LOGGER.warning("FIXME:Attempt to create a widget from a node without a layer in its hierarchy.");
            return null;
        }

        if (scene.getObjects().contains(node)) {
            LOGGER.warning("FIXME:Attempt to create a widget from a node which is already present in the scene");
            return null;
        }

        if (geometrical == null) {
            Geographical geographical = node.getLookup().lookup(Geographical.class);
            if (geographical == null) {
                LOGGER.finest("Attempt to create a widget from a node without a geographical or geometrical, could be a parent node");
                return null;
            } else {
//                for (TypeVariable tv : geographical.getClass().getTypeParameters()) {
//                    if (tv.getGenericDeclaration().getClass().equals(GridCoverage2D.class)) {
//                        LOGGER.finest("Creating GridCoverage2DWidget");
//                        GridCoverage2DWidget widget = new GridCoverage2DWidget(layer.getName(), geographical, layer.getPalette(), geographical.getBoundingBox(), new JXMapGeoTranslator(scene.getMapViewer()), scene);
//                        return widget;
//                    }
//                }
                //FIXME does not always have to result in a GridCoverage2DWidget, unsure how to make this more generic. Only support GridCoverage2DWidget by now
                if (geographical.getBoundingBox() == null) {
                    return null;
                }
                LOGGER.finest("Creating GridCoverage2DWidget");

                final GridCoverage2DWidget widget = new GridCoverage2DWidget(layer.getName(), geographical, palette, geographical.getBoundingBox(), new JXMapGeoTranslator(scene.getMapViewer()), scene);
                if (palette.equals(layer.getPalette())) {
                    layer.addPropertyChangeListener(Layer.PROP_PALETTE, new PropertyChangeListener() {

                        @Override
                        public void propertyChange(PropertyChangeEvent evt) {
                            widget.setPalette((Palette) evt.getNewValue());
                        }
                    });
                }
                addActions(widget, node, scene);
                return widget;
            }
        }

        // support empty geometries:
        if (geometrical.getGeometry() == null) {
            return null;
        }

        GeometricalWidget widget = new GeometricalWidget(scene, new JXMapGeoTranslator(scene.getMapViewer()), geometrical, palette, null);
        addActions(widget, node, scene);

        return widget;
    }

    private static Palette getPalette(Node node, Layer layer) {
        // add palette is present in lookup of node, otherwise use the palette from the layer
        Palette palette = node.getLookup().lookup(Palette.class);
        if (palette == null) {
            LOGGER.finest("using layers palette");
            palette = layer.getPalette();
        } else {
            LOGGER.finest("using palette from node lookup");
        }
        return palette;
    }

    /**
     * Tries to create and returns an icon widget for the given node. No widget
     * is created if the node's lookup doesn't contain a geographical or the
     * geographical doesn't have an icon.
     *
     * @param The node (with a geometrical in its lookup)
     * @return The created icon widget or null if none created.
     */
    static Widget createIconWidgetFromNode(final Node node, MapScene scene) {
        Geometrical geometrical = node.getLookup().lookup(Geometrical.class);
        Layer layer = Layer.Finder.findLayer(node);
        GeoTranslator geoTranslator = new JXMapGeoTranslator(scene.getMapViewer());
        Widget iconWidget = null;
        if (geometrical != null && geometrical.getIcon() != null) {
            iconWidget = new IconWidget(geometrical, getPalette(node, layer), geoTranslator, scene);
            addActions(iconWidget, node, scene);
        }
        return iconWidget;
    }

    /**
     * Adds hover, select and the node's actions to the given widget. Doesn't do
     * anything if the given widget is null. Will first check with {@link MapProperties#getWidgetActionsEnabledValue()}
     * if this actions should be added
     *
     * @param widget The widget to add the actions to. Can be n
     * @param node The node to some of the actions from
     * @param scene The scene the widget is on
     */
    private static void addActions(Widget widget, final Node node, final MapScene scene) {
        if (widget != null) {
            if (MapProperties.getWidgetStateActionsEnabledValue()) {
                widget.getActions().addAction(scene.createObjectHoverAction());
                widget.getActions().addAction(scene.createWidgetHoverAction());
                widget.getActions().addAction(scene.createSelectAction());
            }
            if (MapProperties.getNodeActionsAvailableOnWidgetValue()) {
                widget.getActions().addAction(ActionFactory.createPopupMenuAction(new PopupMenuProvider() {

                    @Override
                    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
                        List actionList = new ArrayList<>();
                        actionList.addAll(Arrays.asList(node.getActions(true)));
                        actionList.add(null);
                        actionList.addAll(Arrays.asList(getMapActions(node, scene)));
                        Action[] actions = actionList.toArray(new Action[actionList.size()]);
                        JPopupMenu menu = Utilities.actionsToPopup(actions, node.getLookup());
                        return menu;
                    }
                }));
            }
        }
    }

    /**
     * Creates and return a list of the map specific actions for the node. Adds
     * the default actions for DynamicGeometrical (currently only
     * PickLocationAction) and checks the DynamicGeometrial for the
     * implementation's specific map actions. Returns an empty list if the node
     * does not contain a DynamicGeometrical.
     *
     * @param node The node
     * @param scene The scene the node's widget is rendered on
     * @return The map specific actions for the node
     */
    private static Action[] getMapActions(final Node node, final MapScene scene) {
        DynamicGeometrical geometrical = node.getLookup().lookup(DynamicGeometrical.class);
        if (geometrical
                != null) {
            return geometrical.getMapActions();
        }
        return new Action[0];
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy