//$HeadURL$ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2008 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.igeo.views.swing; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.ListModel; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.deegree.igeo.ApplicationContainer; import org.deegree.igeo.dataadapter.DataAccessAdapter; import org.deegree.igeo.dataadapter.FeatureAdapter; import org.deegree.igeo.i18n.Messages; import org.deegree.igeo.mapmodel.Layer; import org.deegree.igeo.mapmodel.LayerGroup; import org.deegree.igeo.mapmodel.MapModel; import org.deegree.igeo.mapmodel.MapModelVisitor; import org.deegree.igeo.settings.Settings; import org.deegree.igeo.settings.SnappingLayersOpts; import org.deegree.igeo.settings.SnappingToleranceOpt; import org.deegree.igeo.views.HelpManager; import org.deegree.igeo.views.swing.util.IconRegistry; /** * * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ public class SnappingOptionsPanel extends javax.swing.JPanel { private static final long serialVersionUID = -6326745848985062619L; private JPanel snapOptionsPanel; private JComboBox cbUOM; private JScrollPane scLayers; private JCheckBox cbEdgeCenter; private JLabel jLabel2; private JCheckBox cbEndNode; private JCheckBox cbStartNode; private JCheckBox cbEdge; private JCheckBox cbVertex; private JPanel snapTargetPanel; private JList layerList; private JPanel layerPanel; private JSpinner spSnapDistance; private JLabel jLabel1; private JButton btHelp; private ApplicationContainer<Container> appCont; private Map<String, Layer> featureLayerMap; private ActionListener cbListener = new CheckBoxActionListener(); /** * * @param appCont */ public SnappingOptionsPanel( ApplicationContainer<Container> appCont ) { this.appCont = appCont; featureLayerMap = new HashMap<String, Layer>(); initGUI(); } private void initGUI() { try { final Settings settings = appCont.getSettings(); this.setPreferredSize( new java.awt.Dimension( 360, 311 ) ); GridBagLayout thisLayout = new GridBagLayout(); this.setSize( 360, 311 ); thisLayout.rowWeights = new double[] { 0.0, 0.1 }; thisLayout.rowHeights = new int[] { 234, 7 }; thisLayout.columnWeights = new double[] { 0.1 }; thisLayout.columnWidths = new int[] { 7 }; this.setLayout( thisLayout ); { snapOptionsPanel = new JPanel(); GridBagLayout snapOptionsPanelLayout = new GridBagLayout(); this.add( snapOptionsPanel, new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 0, 0 ), 0, 0 ) ); snapOptionsPanelLayout.rowWeights = new double[] { 0.1, 0.0, 0.1 }; snapOptionsPanelLayout.rowHeights = new int[] { 7, 12, 7 }; snapOptionsPanelLayout.columnWeights = new double[] { 0.0, 0.0, 0.1, 0.1 }; snapOptionsPanelLayout.columnWidths = new int[] { 110, 110, 7, 7 }; snapOptionsPanel.setLayout( snapOptionsPanelLayout ); { btHelp = new JButton(); snapOptionsPanel.add( btHelp, new GridBagConstraints( 2, 2, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); btHelp.setText( Messages.getMessage( getLocale(), "$MD10463" ) ); btHelp.setIcon( IconRegistry.getIcon( "help.png" ) ); btHelp.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { HelpFrame hf = HelpFrame.getInstance( new HelpManager( appCont ) ); hf.setVisible( true ); hf.gotoModule( "Digitizer" ); } } ); } { jLabel1 = new JLabel(); snapOptionsPanel.add( jLabel1, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); jLabel1.setText( Messages.getMessage( getLocale(), "$MD10464" ) ); } { double value = settings.getSnappingToleranceOptions().getValue(); SpinnerNumberModel model = new SpinnerNumberModel( value, 1d, 10000d, 1 ); spSnapDistance = new JSpinner(); snapOptionsPanel.add( spSnapDistance, new GridBagConstraints( 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); spSnapDistance.setModel( model ); spSnapDistance.addChangeListener( new ChangeListener() { public void stateChanged( ChangeEvent e ) { SnappingToleranceOpt smo = settings.getSnappingToleranceOptions(); String value = ( (JSpinner) e.getSource() ).getValue().toString(); smo.setValue( Float.valueOf( value ) ); } } ); } { String[] values = new String[] { Messages.getMessage( getLocale(), "$MD10465" ), Messages.getMessage( getLocale(), "$MD10466" ) }; ComboBoxModel cbUOMModel = new DefaultComboBoxModel( values ); cbUOMModel.setSelectedItem( settings.getSnappingToleranceOptions().getUOM() ); cbUOM = new JComboBox( cbUOMModel ); snapOptionsPanel.add( cbUOM, new GridBagConstraints( 2, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbUOM.addItemListener( new ItemListener() { public void itemStateChanged( ItemEvent e ) { if ( e.getStateChange() == 1 ) { SnappingToleranceOpt smo = settings.getSnappingToleranceOptions(); smo.setUOM( e.getItem().toString() ); } } } ); } } { layerPanel = new JPanel(); GridBagLayout layerPanelLayout = new GridBagLayout(); this.add( layerPanel, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 0, 0 ), 0, 0 ) ); layerPanelLayout.rowWeights = new double[] { 0.1 }; layerPanelLayout.rowHeights = new int[] { 7 }; layerPanelLayout.columnWeights = new double[] { 0.0, 0.1 }; layerPanelLayout.columnWidths = new int[] { 182, 7 }; layerPanel.setLayout( layerPanelLayout ); { scLayers = new JScrollPane(); layerPanel.add( scLayers, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); { List<String> layers = getFeatureLayers(); ListModel layerListModel = new DefaultComboBoxModel( layers.toArray( new String[layers.size()] ) ); layerList = new JList(); layerList.addListSelectionListener( new LayerSelectListener() ); scLayers.setViewportView( layerList ); layerList.setModel( layerListModel ); layerList.addListSelectionListener( new ListSelectionListener() { public void valueChanged( ListSelectionEvent e ) { cbEdge.setEnabled( true ); cbEdgeCenter.setEnabled( true ); cbEndNode.setEnabled( true ); cbStartNode.setEnabled( true ); cbVertex.setEnabled( true ); } } ); } } { snapTargetPanel = new JPanel(); GridBagLayout snapTargetPanelLayout = new GridBagLayout(); layerPanel.add( snapTargetPanel, new GridBagConstraints( 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 0, 0 ), 0, 0 ) ); snapTargetPanelLayout.rowWeights = new double[] { 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1 }; snapTargetPanelLayout.rowHeights = new int[] { 7, 30, 30, 30, 30, 30, 7 }; snapTargetPanelLayout.columnWeights = new double[] { 0.1 }; snapTargetPanelLayout.columnWidths = new int[] { 7 }; snapTargetPanel.setLayout( snapTargetPanelLayout ); { jLabel2 = new JLabel(); snapTargetPanel.add( jLabel2, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); jLabel2.setText( Messages.getMessage( getLocale(), "$MD10467" ) ); } addCheckboxes(); } } } catch ( Exception e ) { e.printStackTrace(); } } private void addCheckboxes() { { cbVertex = new JCheckBox( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); cbVertex.addActionListener( cbListener ); snapTargetPanel.add( cbVertex, new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbVertex.setText( Messages.getMessage( getLocale(), "$MD10468" ) ); cbVertex.setActionCommand( "snapVertex" ); cbVertex.setEnabled( false ); } { cbEdge = new JCheckBox( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); cbEdge.addActionListener( cbListener ); snapTargetPanel.add( cbEdge, new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbEdge.setText( Messages.getMessage( getLocale(), "$MD10469" ) ); cbEdge.setActionCommand( "snapEdge" ); cbEdge.setEnabled( false ); } { cbStartNode = new JCheckBox( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); cbStartNode.addActionListener( cbListener ); snapTargetPanel.add( cbStartNode, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbStartNode.setText( Messages.getMessage( getLocale(), "$MD10470" ) ); cbStartNode.setActionCommand( "snapStartNode" ); cbStartNode.setEnabled( false ); } { cbEndNode = new JCheckBox( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); cbEndNode.addActionListener( cbListener ); snapTargetPanel.add( cbEndNode, new GridBagConstraints( 0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbEndNode.setText( Messages.getMessage( getLocale(), "$MD10471" ) ); cbEndNode.setActionCommand( "snapEndNode" ); cbEndNode.setEnabled( false ); } { cbEdgeCenter = new JCheckBox( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); cbEdgeCenter.addActionListener( cbListener ); snapTargetPanel.add( cbEdgeCenter, new GridBagConstraints( 0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 5 ), 0, 0 ) ); cbEdgeCenter.setText( Messages.getMessage( getLocale(), "$MD10472" ) ); cbEdgeCenter.setActionCommand( "snapEdgeCenter" ); cbEdgeCenter.setEnabled( false ); } } private List<String> getFeatureLayers() throws Exception { SnappingLayersOpts slo = appCont.getSettings().getSnappingLayersOptions(); MapModel mapModel = appCont.getMapModel( null ); CollectFeatureLayersVisitor visitor = new CollectFeatureLayersVisitor( slo ); mapModel.walkLayerTree( visitor ); List<String> list = visitor.getCollectedLayers(); return list; } /** * * @param command * @return {@link ActionListener} assigned to the panel enabling dynamic setting of the panels checkboxes */ public ActionListener createActionListener( String command ) { return new SnapActionListener( command ); } // /////////////////////////////////////////////////////////////////////////////// // inner classes // /////////////////////////////////////////////////////////////////////////////// /** * * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ private class CheckBoxActionListener implements ActionListener { /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed( ActionEvent e ) { JCheckBox cb = (JCheckBox) e.getSource(); if ( cb.isSelected() ) { cb.setIcon( IconRegistry.getIcon( "checkbox_selected.gif" ) ); } else { cb.setIcon( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); } SnappingLayersOpts slo = appCont.getSettings().getSnappingLayersOptions(); String action = cb.getActionCommand(); Object[] values = layerList.getSelectedValues(); for ( int i = 0; i < values.length; i++ ) { Layer layer = featureLayerMap.get( values[i] ); if ( cb.isSelected() ) { if ( action.equals( "snapVertex" ) ) { slo.selectSnappingTargetVertex( layer.getIdentifier(), true ); } else if ( action.equals( "snapEdge" ) ) { slo.selectSnappingTargetEdge( layer.getIdentifier(), true ); } else if ( action.equals( "snapStartNode" ) ) { slo.selectSnappingTargetStartNode( layer.getIdentifier(), true ); } else if ( action.equals( "snapEndNode" ) ) { slo.selectSnappingTargetEndNode( layer.getIdentifier(), true ); } else if ( action.equals( "snapEdgeCenter" ) ) { slo.selectSnappingTargetEdgeCenter( layer.getIdentifier(), true ); } } else { if ( action.equals( "snapVertex" ) ) { slo.selectSnappingTargetVertex( layer.getIdentifier(), false ); } else if ( action.equals( "snapEdge" ) ) { slo.selectSnappingTargetEdge( layer.getIdentifier(), false ); } else if ( action.equals( "snapStartNode" ) ) { slo.selectSnappingTargetStartNode( layer.getIdentifier(), false ); } else if ( action.equals( "snapEndNode" ) ) { slo.selectSnappingTargetEndNode( layer.getIdentifier(), false ); } else if ( action.equals( "snapEdgeCenter" ) ) { slo.selectSnappingTargetEdgeCenter( layer.getIdentifier(), false ); } } } } } /** * * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ private class LayerSelectListener implements ListSelectionListener { /* * (non-Javadoc) * * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent) */ public void valueChanged( ListSelectionEvent e ) { if ( e.getValueIsAdjusting() == false ) { SnappingLayersOpts slo = appCont.getSettings().getSnappingLayersOptions(); JList list = (JList) e.getSource(); int vertex = 0; int edge = 0; int edgeCenter = 0; int startNode = 0; int endNode = 0; Object[] values = list.getSelectedValues(); for ( int i = 0; i < values.length; i++ ) { Layer layer = featureLayerMap.get( values[i] ); if ( slo.isSelectedForSnappingVertices( layer.getIdentifier() ) ) { vertex++; } if ( slo.isSelectedForSnappingEdges( layer.getIdentifier() ) ) { edge++; } if ( slo.isSelectedForSnappingEdgeCenters( layer.getIdentifier() ) ) { edgeCenter++; } if ( slo.isSelectedForSnappingStartNodes( layer.getIdentifier() ) ) { startNode++; } if ( slo.isSelectedForSnappingEndNodes( layer.getIdentifier() ) ) { endNode++; } } updateCheckbox( cbVertex, vertex ); updateCheckbox( cbEdge, edge ); updateCheckbox( cbEdgeCenter, edgeCenter ); updateCheckbox( cbStartNode, startNode ); updateCheckbox( cbEndNode, endNode ); } } private void updateCheckbox( JCheckBox cb, int value ) { if ( value == 0 ) { cb.setSelected( false ); cb.setIcon( IconRegistry.getIcon( "checkbox_unselected.gif" ) ); } else if ( value == 1 ) { cb.setSelected( true ); cb.setIcon( IconRegistry.getIcon( "checkbox_selected.gif" ) ); } else { cb.setSelected( true ); cb.setIcon( IconRegistry.getIcon( "checkbox_indifferent.gif" ) ); } } } /** * * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ public class SnapActionListener implements ActionListener { private String command; /** * * @param command */ public SnapActionListener( String command ) { this.command = command; } /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed( ActionEvent e ) { if ( "vertex".equals( command ) ) { cbVertex.doClick(); } else if ( "edge".equals( command ) ) { cbEdge.doClick(); } else if ( "startnode".equals( command ) ) { cbStartNode.doClick(); } else if ( "endnode".equals( command ) ) { cbEndNode.doClick(); } else if ( "edgecenter".equals( command ) ) { cbEdgeCenter.doClick(); } } } /** * * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ private class CollectFeatureLayersVisitor implements MapModelVisitor { private List<String> layers = new ArrayList<String>( 50 ); private SnappingLayersOpts snappingLayersOpts; private CollectFeatureLayersVisitor( SnappingLayersOpts snappingLayersOpts ) { this.snappingLayersOpts = snappingLayersOpts; } List<String> getCollectedLayers() { return layers; } /* * (non-Javadoc) * * @see org.deegree.igeo.mapmodel.MapModelVisitor#visit(org.deegree.igeo.mapmodel.Layer) */ public void visit( Layer layer ) throws Exception { List<DataAccessAdapter> daa = layer.getDataAccess(); for ( DataAccessAdapter adapter : daa ) { if ( adapter instanceof FeatureAdapter ) { layers.add( layer.getTitle() ); featureLayerMap.put( layer.getTitle(), layer ); snappingLayersOpts.addLayer( layer.getIdentifier() ); break; } } } /* * (non-Javadoc) * * @see org.deegree.igeo.mapmodel.MapModelVisitor#visit(org.deegree.igeo.mapmodel.LayerGroup) */ public void visit( LayerGroup layerGroup ) throws Exception { // do nothing } } }