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.RootMapPanel 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.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import org.jdesktop.swingx.JXPanel;
import eu.limetri.client.mapviewer.api.LayerInfo;
import eu.limetri.client.mapviewer.api.event.GeoEvent;
import eu.limetri.client.mapviewer.data.TileFactoryInfo;
import eu.limetri.client.mapviewer.data.common.TileFactoryInfoSelectionEventHandler;
import eu.limetri.client.mapviewer.data.tilefactory.OSMTileFactoryInfo;
import eu.limetri.client.mapviewer.data.tilefactory.VirtualEarthTileFactoryInfo;
import eu.limetri.client.mapviewer.nb.jxmap.component.SelectionComponent;
import eu.limetri.client.mapviewer.swing.JXMapViewer;
import eu.limetri.client.mapviewer.swing.MapTypeSelectionPanelSwing;
import eu.limetri.client.mapviewer.swing.ZoomPanel;
import eu.limetri.client.mapviewer.swing.impl.OfflineTileFactorySwing;
import eu.limetri.client.mapviewer.swing.jxmap.map.FillLayout;
import eu.limetri.client.mapviewer.swing.jxmap.map.JXMapPanel;
import eu.limetri.client.mapviewer.nb.jxmap.map.LegendPanel;
import eu.limetri.client.mapviewer.swing.jxmap.map.MapMouseEvent;
import eu.limetri.client.mapviewer.swing.jxmap.map.component.LayerSelectionComponent;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Collection;
import nl.cloudfarming.eventbus.GuiEvent;
import nl.cloudfarming.eventbus.GuiEventBus;
import nl.cloudfarming.eventbus.GuiEventKey;
import nl.cloudfarming.eventbus.GuiEventListener;
import org.openide.util.NbBundle;
/**
* The root map panel, containing a layered pane with all the layers. A
* JXMapPanel is used as the bottom layer.
*
* @author Timon Veenstra
*/
@NbBundle.Messages({
"measure_selection_title=Measure",
"measure_length=Length",
"measure_area=Area"})
public class RootMapPanel extends JXPanel implements MapMouseListener {
public enum LayerGroup {
LAYER_MAP(Integer.valueOf(1)),
LAYER_IMAGE(Integer.valueOf(10)),
LAYER_PASSIVE(Integer.valueOf(20)),
LAYER_ACTIVE(Integer.valueOf(29)),
LAYER_DRAWING(Integer.valueOf(30)),
LAYER_LEGEND(Integer.valueOf(49)),
LAYER_TOOLS(Integer.valueOf(52)),
LAYER_LAYERLIST(Integer.valueOf(51)),
LAYER_TOP(Integer.valueOf(50));
private final Integer value;
public Integer getValue() {
return value;
}
private LayerGroup(Integer value) {
this.value = value;
}
}
// swing container holding all layerPanels and the map panel
private final JLayeredPane layerPanelContainer;
// layers
private JXMapPanel mapPanel;
private final JXPanel topPanel = new JXPanel();
//
// map with layerpanels for components
//
private final Set layerPanels = new HashSet<>();
private final MapMouseHandler mouseHandler;
private final ZoomPanel zoomPanel;
private final MapTypeSelectionPanelSwing mapTypeSelectionPanel;
private ToolsPanelEventListener toolsPanelEventListener = new ToolsPanelEventListener();
private static final int ON_TOP = 0;
CardLayout cardLayout;
JPanel panel;
private LayerSelectionComponent layerSelectionComponent;
// private Map layerInfoMap = new HashMap();
public RootMapPanel(final JComponent layerList) {
setLayout(new BorderLayout());
//
// initialize the mouse handler
//
mouseHandler = new MapMouseHandler(this);
//
// the layered pane which will contain the layers of the map
//
layerPanelContainer = new JLayeredPane();
layerPanelContainer.setLayout(new FillLayout());
add(layerPanelContainer, BorderLayout.CENTER);
//
// the map layer
//
mapPanel = new JXMapPanel();
mapPanel.setZoomEnabled(false);
layerPanelContainer.add(mapPanel, LayerGroup.LAYER_MAP.getValue());
//
//zoom controls layer
//
zoomPanel = new ZoomPanel(mapPanel);
zoomPanel.attach();
JPanel mapControlsPanel = new JPanel(new GridBagLayout());
mapControlsPanel.setOpaque(false);
GridBagConstraints gc = new GridBagConstraints();
gc.gridx = 3;
gc.gridy = 1;
gc.weightx = 0;
gc.insets = new Insets(2, 2, 2, 2);
gc.anchor = GridBagConstraints.EAST;
mapControlsPanel.add(zoomPanel, gc); //FIXME miglayout
mapTypeSelectionPanel = new MapTypeSelectionPanelSwing();
VirtualEarthTileFactoryInfo bingMapInfo = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP);
VirtualEarthTileFactoryInfo bingSatelliteInfo = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.SATELLITE);
VirtualEarthTileFactoryInfo bingHybridInfo = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.HYBRID);
TileFactoryInfo openStreetMapInfo = new OSMTileFactoryInfo();
openStreetMapInfo.setIconUrl(RootMapPanel.class.getResource("icons/osm.png"));
bingMapInfo.setIconUrl(RootMapPanel.class.getResource("icons/vem.png"));
bingSatelliteInfo.setIconUrl(RootMapPanel.class.getResource("icons/ves.png"));
bingHybridInfo.setIconUrl(RootMapPanel.class.getResource("icons/veh.png"));
mapTypeSelectionPanel.setItems(new TileFactoryInfo[]{openStreetMapInfo, bingMapInfo, bingSatelliteInfo, bingHybridInfo});
mapTypeSelectionPanel.setOnSelectionChange(new TileFactoryInfoSelectionEventHandler() {
@Override
public void itemSelected(TileFactoryInfo tileFactoryInfo) {
mapPanel.setTileFactory(new OfflineTileFactorySwing(tileFactoryInfo));
}
});
mapTypeSelectionPanel.setActiveTileFactoryInfo(mapPanel.getTileFactory().getInfo());
gc = new GridBagConstraints();
gc.gridx = 2;
gc.gridy = 0;
gc.gridwidth = 2;
gc.insets = new Insets(0, 2, 2, 2);
mapControlsPanel.add(mapTypeSelectionPanel, gc);
layerSelectionComponent = new LayerSelectionComponent();
gc = new GridBagConstraints();
gc.gridx = 1;
gc.gridy = 0;
gc.gridwidth = 1;
gc.insets = new Insets(1, 0, 0, 10);
mapControlsPanel.add(layerSelectionComponent, gc);
gc = new GridBagConstraints();
gc.gridx = 0;
gc.gridy = 10;
gc.weighty = 1;
gc.weightx = 1;
gc.fill = GridBagConstraints.BOTH;
//TODO replace with miglayout
JPanel fillPanel = new JPanel();
fillPanel.setOpaque(false);
mapControlsPanel.add(fillPanel, gc);
layerPanelContainer.add(mapControlsPanel, LayerGroup.LAYER_TOOLS.getValue());
//
// add the layerlist panel
//
JXPanel layerListPanel = new JXPanel();;
if (layerList != null) {
layerListPanel.setOpaque(false);
layerListPanel.setLayout(new MigLayout());
layerListPanel.add(layerList, "wrap");
layerPanelContainer.add(layerListPanel, LayerGroup.LAYER_LAYERLIST.getValue());
mouseHandler.addMapMouseListener(new MapMouseListener() {
@Override
public LayerGroup getGroup() {
return LayerGroup.LAYER_LAYERLIST;
}
@Override
public int getId() {
return 1;
}
@Override
public void onMapMouseEvent(MapMouseEvent mapMouseEvent) {
layerList.dispatchEvent(mapMouseEvent.getEvent());
}
@Override
public void mapMousePressed(MapMouseEvent mapMouseEvent) {
}
@Override
public void mapMouseReleased(MapMouseEvent mapMouseEvent) {
}
@Override
public void mapMouseDragged(MapMouseEvent mapMouseEvent) {
}
});
}
layerPanelContainer.add(new LegendPanel(), LayerGroup.LAYER_LEGEND.getValue());
DrawingController drawingController = new DrawingController(mapPanel);
DrawingPanel drawingPanel = drawingController.getDrawingPanel();
layerPanelContainer.add(drawingPanel, LayerGroup.LAYER_DRAWING.getValue());
JXPanel toolsPanel = drawingController.getToolsPanel();
//layerPanelContainer.add(toolsPanel, LayerGroup.LAYER_TOOLS.getValue());
panel = new JPanel();
cardLayout = new CardLayout();
panel.setLayout(cardLayout);
//TODO FP moving controls panel to same container as zoom component. better solution?
gc = new GridBagConstraints();
gc.gridx = 3;
gc.gridy = 0;
gc.gridheight = 2;
gc.insets = new Insets(0, 2, 2, 0);
gc.anchor = GridBagConstraints.FIRST_LINE_END;
layerListPanel.add(panel, "gaptop 15");
panel.add(toolsPanel, "toolsPanel");
final SelectionComponent combo = new SelectionComponent<>(Bundle.measure_selection_title());
combo.addItem(Bundle.measure_length());
combo.addItem(Bundle.measure_area());
combo.setSelectedIndex(-1);
combo.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (combo.getSelectedIndex() == 0) {
GeoEvent.getProducer().triggerEvent(GeoEvent.MEASURE_LENGTH, null);
} else if (combo.getSelectedIndex() == 1) {
GeoEvent.getProducer().triggerEvent(GeoEvent.MEASURE_AREA, null);
}
}
});
panel.add(combo, "measureCombo");
cardLayout.show(panel, "measureCombo");
topPanel.setOpaque(false);
layerPanelContainer.add(topPanel, LayerGroup.LAYER_TOP.getValue());
topPanel.addMouseListener(mouseHandler);
topPanel.addMouseMotionListener(mouseHandler);
topPanel.addMouseWheelListener(mouseHandler);
GuiEventBus.addListener(toolsPanelEventListener);
setDoubleBuffered(true);
}
public JPanel getTopPanel() {
return topPanel;
}
/**
* returns the mapviewer
*
* @return
*/
public JXMapViewer getMapViewer() {
//FIXME change back to package access
return this.mapPanel;
}
/**
* internal method to add a layerpanel. Only call from the AWT thread.
*
* @param layerPanel
*/
private void internalAddLayerPanel(final LayerPanel layerPanel) {
//
// add interactive layers to the interaction layer
// and add non interactive layer to the object layer
//
mouseHandler.addMapMouseListener(layerPanel);
layerPanels.add(layerPanel);
layerPanelContainer.add(layerPanel, layerPanel.getGroup().getValue(), layerPanel.getInfo().getOrder());
layerPanel.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (LayerInfo.PROPERTY_VISIBLE.equals(evt.getPropertyName())) {
layerPanel.setVisible((Boolean) evt.getNewValue());
}
}
});
}
/**
* add a layer panel
*
* @param layerPanel
*/
public void addLayerPanel(final LayerPanel layerPanel) {
//
// do actual adding in the AWT thread because the scene could be validating and cause
// concurrent modification exception
//
if (EventQueue.isDispatchThread()) {
internalAddLayerPanel(layerPanel);
} else {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
internalAddLayerPanel(layerPanel);
}
});
}
}
/**
* remove a layer panel
*
* @param layerPanel
*/
public void removeLayerPanel(final LayerPanel layerPanel) {
//
// do actual removing in the AWT thread because the scene could be validating and cause
// concurrent modification exception
//
if (EventQueue.isDispatchThread()) {
internalRemoveLayerPanel(layerPanel);
} else {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
internalRemoveLayerPanel(layerPanel);
}
});
}
}
/**
* checks if this panel contains the supplied layerPanel
*
* @param layerPanel
* @return if the supplied layerPanel is contained in this RootMapPanel
*/
boolean contains(final LayerPanel layerPanel) {
return layerPanels.contains(layerPanel);
}
/**
* internal method to remove a layerpanel. Only call from the AWT thread.
*
* @param layerPanel
*/
private void internalRemoveLayerPanel(final LayerPanel layerPanel) {
if (this.layerPanels.contains(layerPanel)) {
this.layerPanels.remove(layerPanel);
}
for (Component c : layerPanelContainer.getComponents()) {
if (c.equals(layerPanel)) {
layerPanelContainer.remove(layerPanel);
}
}
mouseHandler.removeMapMouseListener(layerPanel);
getMapViewer().repaint();
}
@Override
public LayerGroup getGroup() {
return LayerGroup.LAYER_MAP;
}
@Override
public int getId() {
return 1;
}
/**
* dispatches all mouse events to the map when they contain a point
*
* @param mapMouseEvent
*/
@Override
public void onMapMouseEvent(MapMouseEvent mapMouseEvent) {
if (mapMouseEvent.getEvent().getPoint() != null
&& mapPanel.contains(mapMouseEvent.getEvent().getPoint())
&& !SwingUtilities.isRightMouseButton(mapMouseEvent.getEvent())) {
mapPanel.dispatchEvent(mapMouseEvent.getEvent());
}
}
@Override
public void mapMousePressed(MapMouseEvent mapMouseEvent) {
}
@Override
public void mapMouseReleased(MapMouseEvent mapMouseEvent) {
}
@Override
public void mapMouseDragged(MapMouseEvent mapMouseEvent) {
}
private class ToolsPanelEventListener implements GuiEventListener {
Dimension comboDimension;
Dimension toolsDimension = new Dimension(33, 195);
@Override
public void onEvent(GuiEvent event) {
mapPanel.setDoubleClickZoomEnabled(!event.getContent().booleanValue());
if (event.getContent().booleanValue()) {
if (comboDimension == null) {
comboDimension = panel.getSize();
}
panel.setMaximumSize(toolsDimension);
panel.setMinimumSize(toolsDimension);
cardLayout.show(panel, "toolsPanel");
} else {
panel.setMaximumSize(comboDimension);
panel.setMinimumSize(comboDimension);
cardLayout.show(panel, "measureCombo");
}
}
@Override
public boolean listensTo(GuiEventKey guiEventKey) {
return GeoEvent.TOOLS_PANEL.equals(guiEventKey);
}
@Override
public String getModuleName() {
return Module.MODULE_NAME;
}
}
public void repaintReorder(Collection values) {
for (LayerPanel layerPanel: values) {
layerPanelContainer.setPosition(layerPanel, (int)layerPanel.getInfo().getOrder()/2);
}
revalidate();
}
public void refreshSelectedLayer() {
for (LayerPanel layerPanel : layerPanels) {
if (layerPanel.getInfo() != null && layerPanel.getInfo().isSelected()) {
layerPanelContainer.setPosition(layerPanel, ON_TOP);
} else {
layerPanelContainer.setPosition(layerPanel, ((int)layerPanel.getInfo().getOrder()/2) + 1);
}
}
revalidate();
}
}