All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
eu.limetri.client.mapviewer.nb.jxmap.DrawingController Maven / Gradle / Ivy
/**
* 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 eu.limetri.client.mapviewer.nb.jxmap;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JToolBar;
import nl.cloudfarming.eventbus.GuiEvent;
import nl.cloudfarming.eventbus.GuiEventBus;
import nl.cloudfarming.eventbus.GuiEventKey;
import nl.cloudfarming.eventbus.GuiEventListener;
import org.jdesktop.swingx.JXPanel;
import org.openide.nodes.Node;
import org.openide.nodes.NodeEvent;
import org.openide.nodes.NodeListener;
import org.openide.nodes.NodeMemberEvent;
import org.openide.nodes.NodeReorderEvent;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import eu.limetri.client.mapviewer.api.Layer;
import eu.limetri.client.mapviewer.api.SingleObjectLayer;
import eu.limetri.client.mapviewer.api.event.GeoEvent;
import eu.limetri.client.mapviewer.swing.JXMapViewer;
import eu.limetri.client.mapviewer.swing.jxmap.map.AreaMeasurementContext;
import eu.limetri.client.mapviewer.swing.jxmap.map.DrawingContext;
import eu.limetri.client.mapviewer.swing.jxmap.map.LengthMeasurementContext;
import eu.limetri.client.mapviewer.swing.jxmap.map.PolygonDrawingContext;
import eu.limetri.client.mapviewer.swing.jxmap.map.SplitPolygonDrawingContext;
/**
* Controller to control the drawing and splitting of polygons
*
* @author johan
*/
@NbBundle.Messages({
"# {0} - context description", "app_log_start_drawing_context=Started {0}",
"# {0} - context description", "app_log_stop_drawing_context=Finished {0}",})
public class DrawingController {
private static final Logger LOGGER = Logger.getLogger(DrawingController.class.getCanonicalName());
private EditLayerEventListener editLayerEventListener = new EditLayerEventListener();
private SplitLayerEventListener splitLayerEventListener = new SplitLayerEventListener();
private MeasureLengthEventListener measureLengthEventListener = new MeasureLengthEventListener();
private MeasureAreaEventListener measureAreaEventListener = new MeasureAreaEventListener();
private final DrawingPanel drawingPanel;
private final JXPanel toolsPanel;
private DrawingContext context;
private RootNodeListener rootNodeListener = new RootNodeListener();
public DrawingController(JXMapViewer mapPanel) {
this.drawingPanel = new DrawingPanel(mapPanel);
this.toolsPanel = new JXPanel();
toolsPanel.setOpaque(false);
toolsPanel.setLayout(new BorderLayout());
drawingPanel.addNodeListener(rootNodeListener);
// listen for edit requests:
GuiEventBus.addListener(editLayerEventListener);
GuiEventBus.addListener(splitLayerEventListener);
//measure
GuiEventBus.addListener(measureLengthEventListener);
GuiEventBus.addListener(measureAreaEventListener);
}
private void createGeometry(SingleObjectLayer layer) {
startContext(new PolygonDrawingContext(layer, drawingPanel.getMapViewer()));
}
private void editGeometry(SingleObjectLayer layer) {
// TODO
}
private void splitGeometry(Node node) {
startContext(new SplitPolygonDrawingContext(node, drawingPanel.getMapViewer()));
}
/**
* Get the drawing panel this controller controls
*
* @return
*/
public DrawingPanel getDrawingPanel() {
return drawingPanel;
}
/**
* Get the tools panel this controller controls
*
* @return
*/
public JXPanel getToolsPanel() {
return toolsPanel;
}
private void startContext(DrawingContext context) {
// check preconditions:
if (!context.canStart()) {
context.cancel();
return;
}
this.context = context;
// setup toolbar, initial widgets
drawingPanel.addContext(context);
JToolBar tools = new JToolBar(JToolBar.VERTICAL);
for (Action a : context.getActions()) {
tools.add(a);
}
tools.addSeparator();
tools.add(new FinishAction(context, this));
tools.add(new CancelAction(context, this));
tools.setFloatable(false);
toolsPanel.add(tools, BorderLayout.EAST);
toolsPanel.getParent().validate();
GeoEvent.getProducer().triggerEvent(GeoEvent.TOOLS_PANEL, Boolean.TRUE);
LOGGER.info(Bundle.app_log_start_drawing_context(context.getDescription()));
}
private void stopContext(DrawingContext context) {
// remove toolbar & widgets:
drawingPanel.removeContext(context);
toolsPanel.removeAll();
toolsPanel.getParent().repaint();
toolsPanel.getParent().validate();
LOGGER.info(Bundle.app_log_stop_drawing_context(context.getDescription()));
GeoEvent.getProducer().triggerEvent(GeoEvent.TOOLS_PANEL, Boolean.FALSE);
this.context = null;
}
private class EditLayerEventListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
if (!isBusy()) {
SingleObjectLayer layer = event.getContent();
if (layer.hasGeometry()) {
editGeometry(layer);
} else {
createGeometry(layer);
}
} else {
LOGGER.warning("Edit layer requested while editing");
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.EDIT_LAYER.equals(guiEventKey);
}
@Override
public String getModuleName() {
return Module.MODULE_NAME;
}
}
private class SplitLayerEventListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
if (!isBusy()) {
splitGeometry(event.getContent());
} else {
LOGGER.warning("Split layer requested while editing");
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.SPLIT_LAYER.equals(guiEventKey);
}
@Override
public String getModuleName() {
return Module.MODULE_NAME;
}
}
/**
* Checks if busy by checking if the context is null
*
* @return
*/
private boolean isBusy() {
return context != null;
}
/**
* listener for changes in nodes in the explorer manager
*/
private class RootNodeListener implements NodeListener {
private ChildrenListener childrenDestroyedListener = new ChildrenListener();
@Override
public void childrenAdded(NodeMemberEvent ev) {
if (ev.getDelta().length == 1 && !isBusy()) {
Node node = ev.getDelta()[0];
SingleObjectLayer layer = node.getLookup().lookup(SingleObjectLayer.class);
if (layer != null && !layer.hasGeometry()) {
createGeometry(layer);
}
}
for(Node node : ev.getDelta()){
node.addNodeListener(childrenDestroyedListener);
}
}
@Override
public void childrenRemoved(NodeMemberEvent ev) {
nodesRemoved(ev.getDelta());
}
@Override
public void childrenReordered(NodeReorderEvent ev) {
}
@Override
public void nodeDestroyed(NodeEvent ev) {
nodesRemoved(ev.getNode());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
}
public void nodesRemoved(Node... nodes) {
if (isBusy()) {
for (Node node : nodes) {
Layer layer = node.getLookup().lookup(Layer.class);
if (layer != null && layer.equals(context.getLayer())) {
context.cancel();
stopContext(context);
}
}
}
}
/**
* Listens to deletion of children of the root node
*/
private class ChildrenListener 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) {
nodesRemoved(ev.getNode());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
}
}
}
//
// default toolbar actions:
//
@NbBundle.Messages({
"drawing_finish_action_name=Finish",
"drawing_finish_action_tooltip=Finish",
"drawing_finish_action_icon=eu/limetri/client/mapviewer/swing/jxmap/icons/accept24.png"})
private class FinishAction extends AbstractAction {
private final DrawingContext context;
private final DrawingController controller;
public FinishAction(final DrawingContext context, DrawingController controller) {
this.context = context;
this.controller = controller;
putValue(SHORT_DESCRIPTION, Bundle.drawing_finish_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_finish_action_icon(), true));
setEnabled(context.canFinish());
context.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setEnabled(context.canFinish());
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if (context.finish()) {
controller.stopContext(context);
}
}
}
@NbBundle.Messages({
"drawing_cancel_action_name=Cancel",
"drawing_cancel_action_tooltip=Cancel",
"drawing_cancel_action_icon=eu/limetri/client/mapviewer/swing/jxmap/icons/cancel24.png"})
private class CancelAction extends AbstractAction {
private DrawingContext context;
private DrawingController controller;
public CancelAction(DrawingContext context, DrawingController controller) {
this.context = context;
this.controller = controller;
putValue(SHORT_DESCRIPTION, Bundle.drawing_cancel_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_cancel_action_icon(), true));
}
@Override
public void actionPerformed(ActionEvent e) {
context.cancel();
controller.stopContext(context);
}
}
private class MeasureLengthEventListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
if (!isBusy()) {
measureLength();
} else {
LOGGER.warning("Length measurement requested while editing");
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.MEASURE_LENGTH.equals(guiEventKey);
}
@Override
public String getModuleName() {
return Module.MODULE_NAME;
}
}
private class MeasureAreaEventListener implements GuiEventListener {
@Override
public void onEvent(GuiEvent event) {
if (!isBusy()) {
measureArea();
} else {
LOGGER.warning("Area measurement requested while editing");
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.MEASURE_AREA.equals(guiEventKey);
}
@Override
public String getModuleName() {
return Module.MODULE_NAME;
}
}
private void measureLength() {
startContext(new LengthMeasurementContext(drawingPanel.getMapViewer()));
}
private void measureArea() {
startContext(new AreaMeasurementContext(drawingPanel.getMapViewer()));
}
}