nl.cloudfarming.client.geoviewer.jxmap.MapDataManager 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;
import java.beans.PropertyChangeEvent;
import nl.cloudfarming.client.geoviewer.LayerDropTarget;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import nl.cloudfarming.client.geoviewer.Layer;
import nl.cloudfarming.client.geoviewer.event.GeoEvent;
import nl.cloudfarming.client.geoviewer.jxmap.map.FilterMapDataChildren;
import nl.cloudfarming.eventbus.GuiEvent;
import nl.cloudfarming.eventbus.GuiEventBus;
import nl.cloudfarming.eventbus.GuiEventKey;
import nl.cloudfarming.eventbus.GuiEventListener;
import org.openide.explorer.ExplorerManager;
import org.openide.nodes.*;
import org.openide.util.Utilities;
/**
* The MapDataManager provides an optional convenience explorerManager for
* managing data on the map. It is useful to use in combination with a MapView.
*
* In order to receive and manage nodes dropped on the map, the
* MapDataManager
should register itself on the {@link MapView} as
* a {@link LayerDropTarget}.
* mapView.addLayerDropTarget(mapDataManager);
*
* In order to use the MapDataManager as data manager for the map, the
* TopComponent containing the MapView should implement {@link ExplorerManager.Provider}
* and have getExplorerManager to return {@link MapDataManager#getExplorerManager()
* }
*
* @author Timon Veenstra
*/
public class MapDataManager implements ExplorerManager.Provider, LayerDropTarget {
private final ExplorerManager explorerManager = new ExplorerManager();
private final List layerNodes = new ArrayList<>();
private final MapDataRootNodeChildFactory childFactory = new MapDataRootNodeChildFactory();
private final Node rootNode = new AbstractNode(Children.create(childFactory, false));
private final NewLayerListener newLayerListener = new NewLayerListener();
private final DiscardedLayerListener discardedLayerListener = new DiscardedLayerListener();
private static final Logger LOGGER = Logger.getLogger("nl.cloudfarming.client.geoviewer");
private NodeDestroyedListener destroyedListener = new NodeDestroyedListener();
public MapDataManager() {
explorerManager.setRootContext(rootNode);
explorerManager.getRootContext().setDisplayName("");
rootNode.getChildren();
explorerManager.setExploredContext(rootNode);
GuiEventBus.addListener(newLayerListener);
GuiEventBus.addListener(discardedLayerListener);
LOGGER.log(Level.FINE, "MapDataManager::ExplorerManager: {0}", System.identityHashCode(explorerManager));
}
@Override
public ExplorerManager getExplorerManager() {
return explorerManager;
}
@Override
public boolean dropNode(Node node) {
assert node.getLookup().lookup(Layer.class) != null : "Dropped node should always have a layer in its lookup";
addLayerNode(node);
return true;
}
public void addLayerNode(Node layerNode) {
// prevent duplicates
if (!layerNodes.contains(layerNode)) {
layerNodes.add(layerNode);
// Listen for node destroy
layerNode.addNodeListener(destroyedListener);
childFactory.refresh();
Children c = rootNode.getChildren();
for (Node node : c.getNodes()) {
explorerManager.setExploredContext(node);
}
}
}
public void removeLayerNode(Node layerNode) {
if (layerNodes.contains(layerNode)) {
layerNodes.remove(layerNode);
layerNode.removeNodeListener(destroyedListener);
childFactory.refresh();
}
}
public Node[] getLayerNodes() {
return this.layerNodes.toArray(new Node[this.layerNodes.size()]);
}
private class DiscardedLayerListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
Node eventNode = event.getContent();
Layer layer = eventNode.getLookup().lookup(Layer.class);
if (layer == null) {
// no layer found, soft fail
LOGGER.warning("Layer expected in lookup of node passed on with DiscardedLayerEvent");
return;
}
for (Node node : getLayerNodes()) {
if (layer.equals(node.getLookup().lookup(Layer.class))) {
removeLayerNode(node);
}
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.DISCARD_LAYER.equals(guiEventKey);
}
@Override
public String getModuleName() {
return "geoviewer-jxmap";
}
}
/**
* Listener registered on the {@link GuiEventBus} listening to {@link LayerEventKey.NEW_LAYER}
* events.
*
*/
private class NewLayerListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
final Node node = event.getContent();
if (node != null) {
addLayerNode(node);
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.NEW_LAYER.equals(guiEventKey);
}
@Override
public String getModuleName() {
return "geoviewer-jxmap";
}
}
private class NodeDestroyedListener implements NodeListener{
@Override
public void childrenAdded(NodeMemberEvent ev) {
}
@Override
public void childrenRemoved(NodeMemberEvent ev) {
}
@Override
public void childrenReordered(NodeReorderEvent ev) {
}
@Override
public void nodeDestroyed(NodeEvent ev) {
removeLayerNode(ev.getNode());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
}
}
private class MapDataRootNodeChildFactory extends ChildFactory {
public void refresh() {
refresh(true);
}
@Override
protected boolean createKeys(List toPopulate) {
toPopulate.addAll(Arrays.asList(getLayerNodes()));
return true;
}
@Override
protected Node createNodeForKey(final Node key) {
return new FilterNode(key, new FilterMapDataChildren(key));
}
}
}