nl.cloudfarming.client.geoviewer.jxmap.map.MapWidgetFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geoviewer-jxmap Show documentation
Show all versions of geoviewer-jxmap Show documentation
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];
}
}