nl.cloudfarming.client.geoviewer.jxmap.MapView 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.
/**
* Copyright (C) 2010-2012 Agrosense [email protected]
*
* Licensed under the Eclipse Public License - v 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.cloudfarming.client.geoviewer.jxmap;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.ActionMap;
import javax.swing.JComponent;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import nl.cloudfarming.client.geoviewer.Layer;
import nl.cloudfarming.client.geoviewer.LayerInfo;
import nl.cloudfarming.client.geoviewer.jxmap.layerlist.LayerListController;
import nl.cloudfarming.client.geoviewer.jxmap.map.RootMapPanelController;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.nodes.*;
import org.openide.util.Lookup;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
/**
* A view on data managed by an explorer manager. The nodes are represented on a
* map.
*
* Layer nodes are displayed in a layerlist LayerObject nodes contain the
* capability to be displayed on the map
*
*
*
* @author Timon Veenstra
*/
//FIXME cleanup
public class MapView extends JComponent implements Lookup.Provider {
private final LayerListController layerListController = new LayerListController();
private final RootMapPanelController mapPanelController = new RootMapPanelController(layerListController);
private final RootNodeListener rootNodeListener = new RootNodeListener();
// private final Map layerInfoMap = new HashMap();
/**
* Listener to nearly everything
*/
transient MapView.Listener managerListener;
/**
* weak variation of the listener for property change on the explorer
* manager
*/
transient PropertyChangeListener wlpc;
/**
* weak variation of the listener for vetoable change on the explorer
* manager
*/
transient VetoableChangeListener wlvc;
/**
* Explorer manager to work with. Is not null only if the component is
* showing in components hierarchy
*/
private transient ExplorerManager manager;
private final LookupManager lookupManager = new LookupManager();
@Override
protected void processEvent(AWTEvent e) {
super.processEvent(e);
}
/*
* Initilizes the view.
*/
@Override
public void addNotify() {
// super.addNotify();
//
// //
// // find an explorer manager from a parent component
// //
// manager = ExplorerManager.find(this);
// //
// // register a node listener on the root context so we can react on changes
// //
// manager.getRootContext().addNodeListener(rootNodeListener);
// //
// // sycnhronize the layerlist explorer manager with the found explorer manager
// //
// mapPanelController.setParentExplorerManager(manager);
//
//
// //TEST
// System.out.println("MapView::ExplorerManager: " + System.identityHashCode(manager));
super.addNotify();
ExplorerManager em = ExplorerManager.find(this);
if (em != manager) {
if (manager != null) {
manager.removeVetoableChangeListener(wlvc);
manager.removePropertyChangeListener(wlpc);
}
manager = em;
lookupManager.update();
manager.getRootContext().addNodeListener(rootNodeListener);
Node root = manager.getRootContext();
if (root != null) {
addLayersForNewNodes(root);
}
manager.addVetoableChangeListener(wlvc = WeakListeners.vetoableChange(managerListener, manager));
manager.addPropertyChangeListener(wlpc = WeakListeners.propertyChange(managerListener, manager));
updateSelection();
}
}
public MapView() {
setLayout(new BorderLayout());
add(mapPanelController.getPanel(), BorderLayout.CENTER);
}
@Override
public void removeNotify() {
super.removeNotify();
}
public void addLayerDropTarget(LayerDropTarget dropTarget) {
mapPanelController.addLayerDropTarget(dropTarget);
}
@Override
public Lookup getLookup() {
return lookupManager.getProxy();
}
/**
* manages internal lookup and provides proxy
*/
private class LookupManager implements Lookup.Provider {
private Lookup internal = Lookup.EMPTY;
private Lookup proxy = Lookups.proxy(this);
public LookupManager() {
}
void update() {
internal = new ProxyLookup(ExplorerUtils.createLookup(manager, new ActionMap()), layerListController.getLookup());
}
@Override
public Lookup getLookup() {
return internal;
}
public Lookup getProxy() {
return proxy;
}
}
/**
* Recurse through nodes starting from root and add all LayerNodes (which
* are nodes with a Layer object in their lookup)
*
* @param root
*/
void addLayersForNewNodes(Node root) {
Layer layer = root.getLookup().lookup(Layer.class);
// only add nodes with a layer in their lookup
if (layer != null) {
//
// add a property change listener to the layer to respond to propertychanges (refresh)
//
// LayerPropertyChangeListener lpcl = new LayerPropertyChangeListener();
// layer.addPropertyChangeListener(lpcl);
//
// add a layernode listener to listen to changes in the layer node
//
LayerNodeListener layerNodeListener = new LayerNodeListener();
root.addNodeListener(layerNodeListener);
// sync the map explorer manager on the Layer
Layer.Sync.SyncMapExplorer(layer, manager);
//
// add the layer node to the mapPanel through its controller
//
LayerInfo layerInfo = new LayerInfo();
mapPanelController.addLayerNode(root, layerInfo);
layerListController.addLayerNode(root, layerInfo);
}
//
// recurse when children found to see if there are more layers
//
if (root.getChildren() != null && root.getChildren().getNodesCount() > 0) {
for (Node child : root.getChildren().getNodes()) {
addLayersForNewNodes(child);
}
}
}
/**
* Removes layers related to provided nodes and childnodes from the map.
*
* @param layerNodes
*/
void removeLayers(Node... layerNodes) {
for (Node root : layerNodes) {
Layer layer = root.getLookup().lookup(Layer.class);
// only add nodes with a layer in their lookup
if (layer != null) {
mapPanelController.removeLayerNode(root);
layerListController.removeLayerNode(root);
}
//
// recurse when children found to see if there are more layers
//
if (root.getChildren() != null && root.getChildren().getNodesCount() > 0) {
for (Node child : root.getChildren().getNodes()) {
removeLayers(child);
}
}
}
}
/**
* listener for changes in nodes in the explorer manager
*/
private class RootNodeListener implements NodeListener {
@Override
public void childrenAdded(NodeMemberEvent ev) {
for (Node node : ev.getDelta()) {
addLayersForNewNodes(node);
}
}
@Override
public void childrenRemoved(NodeMemberEvent ev) {
removeLayers(ev.getDelta());
}
@Override
public void childrenReordered(NodeReorderEvent ev) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void nodeDestroyed(NodeEvent ev) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
/**
* Listens to changes on a layernode
*
*/
private class LayerNodeListener implements NodeListener {
private void refreshAffectedLayerNodes(NodeMemberEvent ev) {
Set layerNodes = new HashSet();
for (Node node : ev.getDelta()) {
Node layerNode = Layer.Finder.findNodeWithLayer(node);
if (layerNode != null){
layerNodes.add(layerNode);
}
}
for (Node node : layerNodes) {
mapPanelController.refreshLayerNode(node);
}
}
@Override
public void childrenAdded(NodeMemberEvent ev) {
refreshAffectedLayerNodes(ev);
}
@Override
public void childrenRemoved(NodeMemberEvent ev) {
refreshAffectedLayerNodes(ev);
}
@Override
public void childrenReordered(NodeReorderEvent ev) {
// not implemented
}
@Override
public void nodeDestroyed(NodeEvent ev) {
removeLayers(ev.getNode());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
// not implemented
}
}
private final class Listener implements ListDataListener, ListSelectionListener, PropertyChangeListener,
VetoableChangeListener {
Listener() {
}
/**
* Implements
* ListDataListener
interface.
*/
public void intervalAdded(ListDataEvent evt) {
updateSelection();
}
/**
* Implements
* ListDataListener
.
*/
public void intervalRemoved(ListDataEvent evt) {
updateSelection();
}
/**
* Implemetns
* ListDataListener
.
*/
public void contentsChanged(ListDataEvent evt) {
updateSelection();
}
public void vetoableChange(PropertyChangeEvent evt)
throws PropertyVetoException {
if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
Node[] newNodes = (Node[]) evt.getNewValue();
if (!selectionAccept(newNodes)) {
throw new PropertyVetoException("", evt); // NOI18N
}
}
}
public void propertyChange(PropertyChangeEvent evt) {
if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
updateSelection();
return;
}
}
public void valueChanged(ListSelectionEvent e) {
throw new UnsupportedOperationException("valueChanged");
// // forwarding TO E.M., so we won't listen to its cries for a while
// manager.removePropertyChangeListener(wlpc);
// manager.removeVetoableChangeListener(wlvc);
//
//// try {
//// selectionChanged(nodes, manager);
// } catch (PropertyVetoException ex) {
// // selection vetoed - restore previous selection
// updateSelection();
// } finally {
// manager.addPropertyChangeListener(wlpc);
// manager.addVetoableChangeListener(wlvc);
// }
}
}
private boolean selectionAccept(Node[] newNodes) {
throw new UnsupportedOperationException("selectionAccept");
}
private void updateSelection() {
//FIXME do we need to track selection here??
// base and map explorer manager as synced on the layer
// layer panel is listening to selection changes on the layer
// throw new UnsupportedOperationException("updateSelection");
// for (Node node:manager.getSelectedNodes()){
// LayerObject lo = node.getLookup().lookup(LayerObject.class);
// if (lo != null){
//
// }
// }
}
}