[Schmitzm-commits] r1354 - in branches/2.3.x/src: schmitzm/geotools/gui skrueger/geotools skrueger/geotools/labelsearch

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Sat Dec 18 22:58:12 CET 2010


Author: alfonx
Date: 2010-12-18 22:58:10 +0100 (Sat, 18 Dec 2010)
New Revision: 1354

Modified:
   branches/2.3.x/src/schmitzm/geotools/gui/GeoMapPane.java
   branches/2.3.x/src/schmitzm/geotools/gui/JMapEditorToolBar.java
   branches/2.3.x/src/schmitzm/geotools/gui/LayeredMapFrame.java
   branches/2.3.x/src/schmitzm/geotools/gui/XMapPane.java
   branches/2.3.x/src/skrueger/geotools/CrsLabel.java
   branches/2.3.x/src/skrueger/geotools/MapPaneToolBar.java
   branches/2.3.x/src/skrueger/geotools/labelsearch/SearchResultFeature.java
Log:
The XMapPaneListeners of XMapPane are now stored in a WeakHashSet! Every class registering a listener has to keep a reference to the listener, otherwise it will be removed directly! 

Modified: branches/2.3.x/src/schmitzm/geotools/gui/GeoMapPane.java
===================================================================
--- branches/2.3.x/src/schmitzm/geotools/gui/GeoMapPane.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/schmitzm/geotools/gui/GeoMapPane.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -107,7 +107,7 @@
 	 * werden koennen.
 	 */
 	protected JPanel mapPanePanel = null;
-	
+
 	/** Massstab-Balken */
 	private ScalePane scalePane = null;
 	/**
@@ -196,6 +196,60 @@
 	}
 
 	/**
+	 * MapListener that listens to Scale and MapArea changes. This reference is
+	 * needed, otherwise the listener would be removed automatically again.
+	 **/
+	final JMapPaneListener listenToScaleAndMapAreaChanges = new JMapPaneListener() {
+		public void performMapPaneEvent(XMapPaneEvent e) {
+			if (e instanceof ScaleChangedEvent) {
+				ScaleChangedEvent sce = (ScaleChangedEvent) e;
+
+				// If ScalePane expects the units in METERS always. In case
+				// the CRS is not in meters, we convert it to EPSG:3785,
+				// which is meter worldwide.
+
+				CoordinateReferenceSystem mapCrs = getMapPane().getMapContext()
+						.getCoordinateReferenceSystem();
+				CoordinateSystem cs = mapCrs.getCoordinateSystem();
+				if (!(CRSUtilities.getUnit(cs).toString().equals("m"))) {
+					// System.out.println("map cs is not m");
+
+					try {
+
+						// mapArea in "crs" of Map
+						ReferencedEnvelope mapArea = getMapPane().getMapArea();
+
+						// System.out.println("mapArea ° = " + mapArea);
+
+						ReferencedEnvelope transformedMeters = mapArea
+								.transform(GTUtil.WORLD_METER, true);
+
+						// System.out.println("mapArea m = "
+						// + transformedMeters);
+
+						double spanMeters = transformedMeters.getSpan(0);
+
+						getScalePane().setScale(spanMeters / getWidth());
+
+						// getScalePane().setVisible(true); // TODO to often?!
+
+					} catch (Exception transEx) {
+						getScalePane().setScale(0);
+					}
+				} else {
+					// System.out.println("map cs is m");
+					getScalePane().setScale(sce.getNewScale());
+				}
+
+			}
+			if (e instanceof MapAreaChangedEvent) {
+				getVertGrid().repaint();
+				getHorGrid().repaint();
+			}
+		}
+	};
+
+	/**
 	 * Wird vom Konstruktor aufgerufen und initialisiert die grafische
 	 * Darstellung/Anordnung der einzelnen GUI-Komponenten in einem
 	 * {@link GridBagLayout}. Die Constraints fuer die Anordnung der Komponenten
@@ -209,60 +263,8 @@
 		// this.mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
 		SwingUtil.setPreferredWidth(this.mapPane, 200);
 
-		// MapListener that listens to Scale and MapArea changes
-		this.mapPane.addMapPaneListener(new JMapPaneListener() {
-			public void performMapPaneEvent(XMapPaneEvent e) {
-				if (e instanceof ScaleChangedEvent) {
-					ScaleChangedEvent sce = (ScaleChangedEvent) e;
-					
-					
+		this.mapPane.addMapPaneListenerNew(listenToScaleAndMapAreaChanges);
 
-					// If ScalePane expects the units in METERS always. In case
-					// the CRS is not in meters, we convert it to EPSG:3785,
-					// which is meter worldwide.
-					
-					CoordinateReferenceSystem mapCrs = getMapPane()
-							.getMapContext().getCoordinateReferenceSystem();
-					CoordinateSystem cs = mapCrs.getCoordinateSystem();
-					if (!(CRSUtilities.getUnit(cs).toString().equals("m"))) {
-//						System.out.println("map cs is not m");
-
-						try {
-							
-							// mapArea in "crs" of Map
-							ReferencedEnvelope mapArea = getMapPane()
-									.getMapArea();
-
-//							System.out.println("mapArea ° = " + mapArea);
-
-							ReferencedEnvelope transformedMeters = mapArea
-									.transform(GTUtil.WORLD_METER, true);
-
-//							System.out.println("mapArea m = "
-//									+ transformedMeters);
-
-							double spanMeters = transformedMeters.getSpan(0);
-
-							getScalePane().setScale(spanMeters / getWidth());
-							
-//							getScalePane().setVisible(true); // TODO to often?!
-
-						} catch (Exception transEx) {
-							getScalePane().setScale(0);
-						}
-					} else {
-//						System.out.println("map cs is m");
-						getScalePane().setScale(sce.getNewScale());
-					}
-
-				}
-				if (e instanceof MapAreaChangedEvent) {
-					getVertGrid().repaint();
-					getHorGrid().repaint();
-				}
-			}
-		});
-
 		// MapPane nochmal in ein Panel einfuegen, ueber das z.B.
 		// die Border gesteuert werden kann (aufgrund des optimierten
 		// Renderings des XMapPane koennen einige Eigenschaften nicht
@@ -315,18 +317,20 @@
 	}
 
 	// XMapPane ruft setScale jetzt früh genug auf. Nicht mehr nötig
-//	/**
-//	 * Nach dem {@code super}-Aufruf, wird der Massstab neu gesetzt (und somit
-//	 * neu angezeigt), falls sich der Massstab der Karte geaendert hat. Dies ist
-//	 * ein Workaround, damit der Massstab auch beim allerersten anzeigen korrekt
-//	 * angezeigt wird (ohne {@link ScaleChangedEvent}).
-//	 */
-//	public void paint(Graphics g) {
-//		super.paint(g);
-//		if (getScalePane().getScaleInMeters() != mapPane.getScale()
-//				&& mapPane.getScale() > 0)
-//			getScalePane().setScale(mapPane.getScale());
-//	}
+	// /**
+	// * Nach dem {@code super}-Aufruf, wird der Massstab neu gesetzt (und somit
+	// * neu angezeigt), falls sich der Massstab der Karte geaendert hat. Dies
+	// ist
+	// * ein Workaround, damit der Massstab auch beim allerersten anzeigen
+	// korrekt
+	// * angezeigt wird (ohne {@link ScaleChangedEvent}).
+	// */
+	// public void paint(Graphics g) {
+	// super.paint(g);
+	// if (getScalePane().getScaleInMeters() != mapPane.getScale()
+	// && mapPane.getScale() > 0)
+	// getScalePane().setScale(mapPane.getScale());
+	// }
 
 	/**
 	 * Liefert das {@link SelectableXMapPane}, in dem die Karten dargestellt
@@ -366,8 +370,7 @@
 	 * @return If dispose() has been called. If
 	 *         <code>true<(code>, further use of this {@link GeoMapPane} is undefined
 	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Tzeggai</a>
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
 	 */
 	public boolean isDisposed() {
 		return disposed;
@@ -377,8 +380,7 @@
 	 * Should be called when the {@link GeoMapPane} is not needed no more to
 	 * help the GarbageCollector
 	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Tzeggai</a>
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
 	 */
 	public void dispose() {
 
@@ -397,8 +399,7 @@
 	 * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
 	 * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
 	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Tzeggai</a>
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
 	 */
 	@Override
 	public void print(Graphics g) {

Modified: branches/2.3.x/src/schmitzm/geotools/gui/JMapEditorToolBar.java
===================================================================
--- branches/2.3.x/src/schmitzm/geotools/gui/JMapEditorToolBar.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/schmitzm/geotools/gui/JMapEditorToolBar.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -55,477 +55,536 @@
 
 /**
  * A toolbar to control the operations of a {@link JMapEditorPane}.
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * 
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *         (University of Bonn/Germany)
  */
 public class JMapEditorToolBar extends JToolBar {
-	private static final Logger LOGGER = Logger.getLogger(JMapEditorToolBar.class.getName());
+	private static final Logger LOGGER = Logger
+			.getLogger(JMapEditorToolBar.class.getName());
 	/** Constant for the tool "New layer" (10). */
 	public static final int LAYER_NEW = 10;
-    /** Constant for the tool "Save layer" (20). */
-    public static final int LAYER_SAVE = 20;
-    /** Constant for the tool "Cancel layer" (30). */
-    public static final int LAYER_CANCEL = 30;
-    /** Constant for the tool "Undo all editor actions" (100). */
-    public static final int EDIT_CLEAR = 100;
+	/** Constant for the tool "Save layer" (20). */
+	public static final int LAYER_SAVE = 20;
+	/** Constant for the tool "Cancel layer" (30). */
+	public static final int LAYER_CANCEL = 30;
+	/** Constant for the tool "Undo all editor actions" (100). */
+	public static final int EDIT_CLEAR = 100;
 	/** Constant for the tool "Undo last editor action" (110). */
 	public static final int EDIT_UNDO = 110;
 	/** Constant for the tool "Redo last undone editor action" (120). */
 	public static final int EDIT_REDO = 120;
-    /** Constant for the tool "Finish current segment" (130). */
-    public static final int EDIT_FINISH = 130;
+	/** Constant for the tool "Finish current segment" (130). */
+	public static final int EDIT_FINISH = 130;
 
-    /** Holds the action buttons of the bar. */
-    protected SortedMap<Integer, JButton> actionButtons = null;
+	/** Holds the action buttons of the bar. */
+	protected SortedMap<Integer, JButton> actionButtons = null;
 
 	/** Holds the {@link JMapEditorPane} this tool bar controls. */
 	protected JMapEditorPane editorPane = null;
-	
-	/** Holds the listener, that reacts on editor actions. */
-	protected JMapPaneListener mapPaneListener = null;
 
-    /**
-     * Creates a new toolbar. Notice: This toolbar does nothing
-     * until {@link #setMapPane(JMapEditorPane)} is called!
-     */
-    public JMapEditorToolBar() {
-      this(null);
-    }
-    
-    /**
+	/**
+	 * Holds the listener, that reacts on editor actions. A reference to this
+	 * listner is needed!
+	 */
+	protected final JMapPaneListener mapPaneListener;
+
+	/**
+	 * Creates a new toolbar. Notice: This toolbar does nothing until
+	 * {@link #setMapPane(JMapEditorPane)} is called!
+	 */
+	public JMapEditorToolBar() {
+		this(null);
+	}
+
+	/**
 	 * Creates a new tool bar.
-	 * @param editorPane {@link JMapEditorPane} the tool bar controls
+	 * 
+	 * @param editorPane
+	 *            {@link JMapEditorPane} the tool bar controls
 	 */
 	public JMapEditorToolBar(JMapEditorPane editorPane) {
-	  super("Control the editor actions", JToolBar.HORIZONTAL);
-      this.actionButtons   = new TreeMap<Integer,JButton>();
-      // Create a Listener to sniff the zooms on the JMapPane
-      this.mapPaneListener = new JMapPaneListener() {
-          public void performMapPaneEvent(XMapPaneEvent e) {
-              if ( !(e instanceof JEditorPaneEvent) )
-                return;
+		super("Control the editor actions", JToolBar.HORIZONTAL);
+		this.actionButtons = new TreeMap<Integer, JButton>();
+		// Create a Listener to sniff the zooms on the JMapPane
+		this.mapPaneListener = new JMapPaneListener() {
+			public void performMapPaneEvent(XMapPaneEvent e) {
+				if (!(e instanceof JEditorPaneEvent))
+					return;
 
-              // At the moment the layer editing is finished, the editor mode
-              // is not yet initialized. However for the button activation the
-              // mode NULL is essential in this case.
-              EditorMode mode = ((JEditorPaneEvent)e).getEditorMode();
-              if ( e instanceof LayerEditCanceledEvent ||
-                   e instanceof LayerEditFinishedEvent )
-                mode = null;
-              updateButtonActivation(mode);
-          }
-      };    
-     
-      setMapPane(editorPane);
-	  setFloatable(false);
-	  setRollover(true);
-	  
-	  init();
+				// At the moment the layer editing is finished, the editor mode
+				// is not yet initialized. However for the button activation the
+				// mode NULL is essential in this case.
+				EditorMode mode = ((JEditorPaneEvent) e).getEditorMode();
+				if (e instanceof LayerEditCanceledEvent
+						|| e instanceof LayerEditFinishedEvent)
+					mode = null;
+				updateButtonActivation(mode);
+			}
+		};
+
+		setMapPane(editorPane);
+		setFloatable(false);
+		setRollover(true);
+
+		init();
 	}
-	
+
 	/**
 	 * Sets the {@link JMapEditorPane} controlled by this tool bar.
-	 * @param editorPane {@link JMapEditorPane} to control (if {@code null} this
-	 *                   tool bar controls NOTHING!)
+	 * 
+	 * @param editorPane
+	 *            {@link JMapEditorPane} to control (if {@code null} this tool
+	 *            bar controls NOTHING!)
 	 */
 	public void setMapPane(JMapEditorPane editorPane) {
-	  // Remove listener from old MapPane
-	  if ( this.editorPane != null )
-	    this.editorPane.removeMapPaneListener( mapPaneListener );
-      this.editorPane = editorPane;
-      if ( this.editorPane != null && mapPaneListener != null )
-        this.editorPane.addMapPaneListener( mapPaneListener );
+		// Remove listener from old MapPane
+		if (this.editorPane != null)
+			this.editorPane.removeMapPaneListener(mapPaneListener);
+		this.editorPane = editorPane;
+		if (this.editorPane != null && mapPaneListener != null)
+			this.editorPane.addMapPaneListenerNew(mapPaneListener);
 	}
-	
+
 	/**
-	 * Calls {@link #initActions()} and then puts all action buttons
-	 * to the tool bar.
+	 * Calls {@link #initActions()} and then puts all action buttons to the tool
+	 * bar.
 	 */
 	protected void init() {
-	  initActions();
-	  initToolBar();
-	  updateButtonActivation(null);
+		initActions();
+		initToolBar();
+		updateButtonActivation(null);
 	}
 
-    /**
-     * Creates the action buttons and adds them to {@link #actionButtons}.
-     */
-    protected void initActions() {
-      // Action button to create a new layer
-      addAction( new EditorPaneToolBarAction(
-          LAYER_NEW,
-          this,
-          "button.layer.new",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/layer_new.png"))
-      ), false);
+	/**
+	 * Creates the action buttons and adds them to {@link #actionButtons}.
+	 */
+	protected void initActions() {
+		// Action button to create a new layer
+		addAction(
+				new EditorPaneToolBarAction(LAYER_NEW, this,
+						"button.layer.new",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/layer_new.png"))),
+				false);
 
-      // Action button to finish a layer
-      addAction( new EditorPaneToolBarAction(
-          LAYER_SAVE,
-          this,
-          "button.layer.save",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/layer_finish.png"))
-      ), false);
+		// Action button to finish a layer
+		addAction(
+				new EditorPaneToolBarAction(
+						LAYER_SAVE,
+						this,
+						"button.layer.save",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/layer_finish.png"))),
+				false);
 
-      // Action button to cancel a layer
-      addAction( new EditorPaneToolBarAction(
-          LAYER_CANCEL,
-          this,
-          "button.layer.cancel",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/layer_cancel.png"))
-      ), false);
+		// Action button to cancel a layer
+		addAction(
+				new EditorPaneToolBarAction(
+						LAYER_CANCEL,
+						this,
+						"button.layer.cancel",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/layer_cancel.png"))),
+				false);
 
-      // Action button to undo all editing action
-      addAction( new EditorPaneToolBarAction(
-          EDIT_CLEAR,
-          this,
-          "button.edit.clear",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/edit_clear.png"))
-      ), false);
+		// Action button to undo all editing action
+		addAction(
+				new EditorPaneToolBarAction(EDIT_CLEAR, this,
+						"button.edit.clear", new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/edit_clear.png"))),
+				false);
 
-      // Action button to undo a editing action
-      addAction( new EditorPaneToolBarAction(
-          EDIT_UNDO,
-          this,
-          "button.edit.undo",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/edit_undo.png"))
-      ), false);
+		// Action button to undo a editing action
+		addAction(
+				new EditorPaneToolBarAction(EDIT_UNDO, this,
+						"button.edit.undo",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/edit_undo.png"))),
+				false);
 
-      // Action button to redo a undone editing action
-      addAction( new EditorPaneToolBarAction(
-          EDIT_REDO,
-          this,
-          "button.edit.redo",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/edit_redo.png"))
-      ), false);
+		// Action button to redo a undone editing action
+		addAction(
+				new EditorPaneToolBarAction(EDIT_REDO, this,
+						"button.edit.redo",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/edit_redo.png"))),
+				false);
 
-      // Action button to finish a feature
-      addAction( new EditorPaneToolBarAction(
-          EDIT_FINISH,
-          this,
-          "button.edit.finish",
-          new ImageIcon(JMapEditorPane.class.getResource("resource/icons/edit_finish.png"))
-      ), false);
-    }
-    
-    /**
-     * Clears the GUI of all components and adds all action buttons to the
-     * tool bar.
-     */
-    protected void initToolBar() {
-      setAlignmentY( 1f );
-      removeAll();
-//      // Separator to the left of the tool actions to start
-//      // the tool buttons with the map (not with the coordinate grid)
-//      Dimension dimension = new Dimension( 49,10);
-//      addSeparator(dimension);
-//      // Space between tool buttons and action buttons
-//      Dimension dimension2 = new Dimension( 10,10);
-//      this.addSeparator(dimension2);
-      // Action buttons
-      for (JButton b : actionButtons.values())
-        add(b);
-    }
-    
+		// Action button to finish a feature
+		addAction(
+				new EditorPaneToolBarAction(EDIT_FINISH, this,
+						"button.edit.finish",
+						new ImageIcon(JMapEditorPane.class
+								.getResource("resource/icons/edit_finish.png"))),
+				false);
+	}
 
-    /**
-     * Performs the action of an action button.
-     * @param tool the action
-     * @param e    the event of the button
-     */
+	/**
+	 * Clears the GUI of all components and adds all action buttons to the tool
+	 * bar.
+	 */
+	protected void initToolBar() {
+		setAlignmentY(1f);
+		removeAll();
+		// // Separator to the left of the tool actions to start
+		// // the tool buttons with the map (not with the coordinate grid)
+		// Dimension dimension = new Dimension( 49,10);
+		// addSeparator(dimension);
+		// // Space between tool buttons and action buttons
+		// Dimension dimension2 = new Dimension( 10,10);
+		// this.addSeparator(dimension2);
+		// Action buttons
+		for (JButton b : actionButtons.values())
+			add(b);
+	}
+
+	/**
+	 * Performs the action of an action button.
+	 * 
+	 * @param tool
+	 *            the action
+	 * @param e
+	 *            the event of the button
+	 */
 	protected void performActionButton(int action, ActionEvent e) {
-      if ( editorPane == null )
-        return;
-      
-      try {
-        // Perform the action "New layer"
-        if ( action == LAYER_NEW )
-          createNewLayer();
-        // Perform the action "Finish layer"
-        if ( action == LAYER_SAVE )
-          editorPane.finishEditing();
-        // Perform the action "Cancel layer"
-        if ( action == LAYER_CANCEL )
-          editorPane.cancelEditing();
-  
-        // Perform the action "Finish feature"
-        if ( action == EDIT_FINISH )
-          editorPane.finishFeature();
-        // Perform the action "Undo editing"
-        if ( action == EDIT_UNDO )
-          editorPane.undoEditing();
-        // Perform the action "Redo editing"
-        if ( action == EDIT_REDO )
-          editorPane.redoEditing();
-        // Perform the action "Clear editing"
-        if ( action == EDIT_CLEAR )
-          editorPane.undoAll();
-      } catch (Exception err) {
-        ExceptionDialog.show(err);
-      }
+		if (editorPane == null)
+			return;
+
+		try {
+			// Perform the action "New layer"
+			if (action == LAYER_NEW)
+				createNewLayer();
+			// Perform the action "Finish layer"
+			if (action == LAYER_SAVE)
+				editorPane.finishEditing();
+			// Perform the action "Cancel layer"
+			if (action == LAYER_CANCEL)
+				editorPane.cancelEditing();
+
+			// Perform the action "Finish feature"
+			if (action == EDIT_FINISH)
+				editorPane.finishFeature();
+			// Perform the action "Undo editing"
+			if (action == EDIT_UNDO)
+				editorPane.undoEditing();
+			// Perform the action "Redo editing"
+			if (action == EDIT_REDO)
+				editorPane.redoEditing();
+			// Perform the action "Clear editing"
+			if (action == EDIT_CLEAR)
+				editorPane.undoAll();
+		} catch (Exception err) {
+			ExceptionDialog.show(err);
+		}
 	}
-	
+
 	/**
-	 * Sets the enables/disables property for every toolbar button according 
-	 * to the current editor state. 
-	 * @param editorMode editor mode (because some events are fired BEFORE
-	 *                   the new mode is set)
+	 * Sets the enables/disables property for every toolbar button according to
+	 * the current editor state.
+	 * 
+	 * @param editorMode
+	 *            editor mode (because some events are fired BEFORE the new mode
+	 *            is set)
 	 */
 	protected void updateButtonActivation(EditorMode editorMode) {
-	  if ( editorPane == null ) {
-	    setAllActionsEnabled(false, false);
-	    return;
-	  }
-      getButton( LAYER_NEW ).setEnabled( editorMode == null );
-	  getButton( LAYER_SAVE ).setEnabled( editorMode != null );
-      getButton( LAYER_CANCEL ).setEnabled( editorMode != null );
-      getButton( EDIT_UNDO ).setEnabled( editorPane.isUndoPossible() );
-      getButton( EDIT_REDO ).setEnabled( editorPane.isRedoPossible() );
-      getButton( EDIT_CLEAR ).setEnabled( editorPane.isUndoPossible() );
-      getButton( EDIT_FINISH ).setEnabled( editorMode != null && editorMode != EditorMode.New_Point );
+		if (editorPane == null) {
+			setAllActionsEnabled(false, false);
+			return;
+		}
+		getButton(LAYER_NEW).setEnabled(editorMode == null);
+		getButton(LAYER_SAVE).setEnabled(editorMode != null);
+		getButton(LAYER_CANCEL).setEnabled(editorMode != null);
+		getButton(EDIT_UNDO).setEnabled(editorPane.isUndoPossible());
+		getButton(EDIT_REDO).setEnabled(editorPane.isRedoPossible());
+		getButton(EDIT_CLEAR).setEnabled(editorPane.isUndoPossible());
+		getButton(EDIT_FINISH).setEnabled(
+				editorMode != null && editorMode != EditorMode.New_Point);
 	}
-	
+
 	/**
 	 * Starts new layer.
 	 */
 	protected void createNewLayer() {
-	  // Ask layer type and name
-	  ManualInputOption.Text titleOption = new ManualInputOption.Text(
-	      getResourceString("NewLayer.layer.title"), true, getResourceString("NewLayer.layer.title.default")
-      );
-	  SelectionInputOption.Radio<JMapEditorPane.EditorMode> typeOption = new SelectionInputOption.Radio<JMapEditorPane.EditorMode>(
-          getResourceString("NewLayer.layer.type"),
-          true,
-          new JMapEditorPane.EditorMode[] { EditorMode.New_Point, EditorMode.New_Line, EditorMode.New_Polygon },
-          new String[] { getResourceString("NewLayer.layer.type.point"), getResourceString("NewLayer.layer.type.line"), getResourceString("NewLayer.layer.type.polygon") }
-	  );
-	  FeatureTypeInputOption ftOption = new FeatureTypeInputOption(
-	      getResourceString("NewLayer.ftype.title"),
-	      false
-	  ) {
-	        // Checks whether "the_geom" is used as attribute name
-	        // --> not allowed because JEditorPane uses this attribute
-	        //     for the default geometry of new layers
-    	    public boolean performIsInputValid() {
-    	      if ( super.performIsInputValid() ) {
-    	        SimpleFeatureType ft = inpTableModel.createFeatureType();
-    	        if ( ft.getDescriptor( JMapEditorPane.GEOMETRY_ATTR ) != null )
-    	          throw new UnsupportedOperationException(getResourceString("NewLayer.Err.GeomAttr",JMapEditorPane.GEOMETRY_ATTR));
-    	      }
-    	      return true;
-    	    }
-	  };
-	  Object[] value = MultipleOptionPane.showMultipleInputDialog(
-	      this,
-	      getResourceString("NewLayer.dialog.title"),
-	      titleOption,
-	      typeOption,
-	      ftOption
-	  );
-	  if ( value == null )
-	    return; // Dialog canceled
-	  editorPane.setAdditionalAttributes( ftOption.getValue() );
-	  editorPane.startEditing(
-	      (JMapEditorPane.EditorMode)value[1],
-	      (String)value[0]
-	  );
+		// Ask layer type and name
+		ManualInputOption.Text titleOption = new ManualInputOption.Text(
+				getResourceString("NewLayer.layer.title"), true,
+				getResourceString("NewLayer.layer.title.default"));
+		SelectionInputOption.Radio<JMapEditorPane.EditorMode> typeOption = new SelectionInputOption.Radio<JMapEditorPane.EditorMode>(
+				getResourceString("NewLayer.layer.type"), true,
+				new JMapEditorPane.EditorMode[] { EditorMode.New_Point,
+						EditorMode.New_Line, EditorMode.New_Polygon },
+				new String[] { getResourceString("NewLayer.layer.type.point"),
+						getResourceString("NewLayer.layer.type.line"),
+						getResourceString("NewLayer.layer.type.polygon") });
+		FeatureTypeInputOption ftOption = new FeatureTypeInputOption(
+				getResourceString("NewLayer.ftype.title"), false) {
+			// Checks whether "the_geom" is used as attribute name
+			// --> not allowed because JEditorPane uses this attribute
+			// for the default geometry of new layers
+			public boolean performIsInputValid() {
+				if (super.performIsInputValid()) {
+					SimpleFeatureType ft = inpTableModel.createFeatureType();
+					if (ft.getDescriptor(JMapEditorPane.GEOMETRY_ATTR) != null)
+						throw new UnsupportedOperationException(
+								getResourceString("NewLayer.Err.GeomAttr",
+										JMapEditorPane.GEOMETRY_ATTR));
+				}
+				return true;
+			}
+		};
+		Object[] value = MultipleOptionPane.showMultipleInputDialog(this,
+				getResourceString("NewLayer.dialog.title"), titleOption,
+				typeOption, ftOption);
+		if (value == null)
+			return; // Dialog canceled
+		editorPane.setAdditionalAttributes(ftOption.getValue());
+		editorPane.startEditing((JMapEditorPane.EditorMode) value[1],
+				(String) value[0]);
 	}
 
-    /**
-     * Adds an action to the tool bar. Does nothing if a tool or action with the
-     * specified ID already exists!
-     * @param buttonAction action for the button
-     * @param resetToolBar indicates whether the toolbar GUI is reset after adding
-     *                     the button (if adding several actions it useful only to
-     *                     reset the GUI for the last added tool) 
-     */
-    public void addAction(EditorPaneToolBarAction buttonAction, boolean resetToolBar) {
-      if ( isButtonIDUsed(buttonAction.getID()) ) {
-        LOGGER.warn("addAction(.) ignored because ID already used for tool or action: "+buttonAction.getID());
-        return;
-      }
-      JButton button = new JButton(buttonAction);
-      actionButtons.put( buttonAction.getID(), button );
-      if ( resetToolBar )
-        initToolBar();
-    }
+	/**
+	 * Adds an action to the tool bar. Does nothing if a tool or action with the
+	 * specified ID already exists!
+	 * 
+	 * @param buttonAction
+	 *            action for the button
+	 * @param resetToolBar
+	 *            indicates whether the toolbar GUI is reset after adding the
+	 *            button (if adding several actions it useful only to reset the
+	 *            GUI for the last added tool)
+	 */
+	public void addAction(EditorPaneToolBarAction buttonAction,
+			boolean resetToolBar) {
+		if (isButtonIDUsed(buttonAction.getID())) {
+			LOGGER.warn("addAction(.) ignored because ID already used for tool or action: "
+					+ buttonAction.getID());
+			return;
+		}
+		JButton button = new JButton(buttonAction);
+		actionButtons.put(buttonAction.getID(), button);
+		if (resetToolBar)
+			initToolBar();
+	}
 
-    /**
-     * Adds an action to the tool bar and resets the toolbar GUI.
-     * @param buttonAction action for the toggle button
-     */
-    public void addAction(EditorPaneToolBarAction buttonAction) {
-      addAction(buttonAction, true);
-    }
-    
-    /**
-     * Returns the button for a specific tool or action.
-     * @param id the constant for a tool
-     * @return a {@link JButton} if {@code id} specifies an {@linkplain #getActionButton(int) action button}
-     *         or {@link JToogleButton} if {@code id} specifies a {@linkplain #getToolButton(int) tool button}
-     */
-    public AbstractButton getButton(int id) {
-      AbstractButton button = actionButtons.get(id);
-      if ( button == null )
-        LOGGER.warn("Unknown action ID: "+id);
-      return button;
-    }
+	/**
+	 * Adds an action to the tool bar and resets the toolbar GUI.
+	 * 
+	 * @param buttonAction
+	 *            action for the toggle button
+	 */
+	public void addAction(EditorPaneToolBarAction buttonAction) {
+		addAction(buttonAction, true);
+	}
 
-    /**
-     * Returns the button for a specific action.
-     * @param action the constant an action 
-     */
-    public JButton getActionButton(int action) {
-      AbstractButton button = getButton(action);
-      if ( button != null && !(button instanceof JButton) ) {
-        LOGGER.warn("ID specifies no action: "+action);
-        button = null;
-      }
-      return (JButton)button; 
+	/**
+	 * Returns the button for a specific tool or action.
+	 * 
+	 * @param id
+	 *            the constant for a tool
+	 * @return a {@link JButton} if {@code id} specifies an
+	 *         {@linkplain #getActionButton(int) action button} or
+	 *         {@link JToogleButton} if {@code id} specifies a
+	 *         {@linkplain #getToolButton(int) tool button}
+	 */
+	public AbstractButton getButton(int id) {
+		AbstractButton button = actionButtons.get(id);
+		if (button == null)
+			LOGGER.warn("Unknown action ID: " + id);
+		return button;
+	}
 
-    }
+	/**
+	 * Returns the button for a specific action.
+	 * 
+	 * @param action
+	 *            the constant an action
+	 */
+	public JButton getActionButton(int action) {
+		AbstractButton button = getButton(action);
+		if (button != null && !(button instanceof JButton)) {
+			LOGGER.warn("ID specifies no action: " + action);
+			button = null;
+		}
+		return (JButton) button;
 
-    /**
-     * Sets whether an action is activated or not. The visible property
-     * of the button is not affected.
-     * @param id actionID
-     * @param enabled if {@code true} the action becomes available
-     */
-    public void setButtonEnabled(int id, boolean enabled) {
-      AbstractButton button = getButton(id);
-      if ( button == null )
-        return;
-      button.setEnabled( enabled );
-    }
+	}
 
-    /**
-     * Sets whether an action is activated or not.
-     * @param id actionID
-     * @param enabled if {@code true} the tool becomes available
-     * @param hideOnDisable if {@code true} the button is also hidden if
-     *                      {@code enabled} is {@code false}
-     */
+	/**
+	 * Sets whether an action is activated or not. The visible property of the
+	 * button is not affected.
+	 * 
+	 * @param id
+	 *            actionID
+	 * @param enabled
+	 *            if {@code true} the action becomes available
+	 */
+	public void setButtonEnabled(int id, boolean enabled) {
+		AbstractButton button = getButton(id);
+		if (button == null)
+			return;
+		button.setEnabled(enabled);
+	}
+
+	/**
+	 * Sets whether an action is activated or not.
+	 * 
+	 * @param id
+	 *            actionID
+	 * @param enabled
+	 *            if {@code true} the tool becomes available
+	 * @param hideOnDisable
+	 *            if {@code true} the button is also hidden if {@code enabled}
+	 *            is {@code false}
+	 */
 	public void setButtonEnabled(int id, boolean enabled, boolean hideOnDisable) {
-	  AbstractButton button = getButton(id);
-	  if ( button == null )
-	    return;
-	  button.setEnabled( enabled );
-	  // if button is enabled, it becomes visible anyway
-	  // if button is disabled and the "hide" option is set, it is also hidden 
-	  if ( enabled )
-	    button.setVisible( true );
-	  else
-	    button.setVisible( !hideOnDisable );
+		AbstractButton button = getButton(id);
+		if (button == null)
+			return;
+		button.setEnabled(enabled);
+		// if button is enabled, it becomes visible anyway
+		// if button is disabled and the "hide" option is set, it is also hidden
+		if (enabled)
+			button.setVisible(true);
+		else
+			button.setVisible(!hideOnDisable);
 	}
 
-    /**
-     * Checks whether a ID is already used for a tool or action.
-     * @param tool tool ID
-     */
-    public boolean isButtonIDUsed(int id) {
-      return actionButtons.get(id) != null;
-    }
+	/**
+	 * Checks whether a ID is already used for a tool or action.
+	 * 
+	 * @param tool
+	 *            tool ID
+	 */
+	public boolean isButtonIDUsed(int id) {
+		return actionButtons.get(id) != null;
+	}
 
-    /**
-     * Checks whether a tool is activated.
-     * @param tool tool ID
-     * @return {@code false} if an unknown ID is specified
-     */
-    public boolean isButtonEnabled(int id) {
-      AbstractButton button = getButton(id);
-      if ( button != null )
-        return button.isEnabled();
-      return false;
-    }
+	/**
+	 * Checks whether a tool is activated.
+	 * 
+	 * @param tool
+	 *            tool ID
+	 * @return {@code false} if an unknown ID is specified
+	 */
+	public boolean isButtonEnabled(int id) {
+		AbstractButton button = getButton(id);
+		if (button != null)
+			return button.isEnabled();
+		return false;
+	}
 
-    /**
-     * Sets the activation for all actions.
-     * @param enabled if {@code true} all actions becomes available
-     * @param hideOnDisable if {@code true} the buttons are also hidden if
-     *                      {@code enabled} is {@code false}
-     */
-    public void setAllActionsEnabled(boolean enabled, boolean hideOnDisable) {
-      for (int tool : actionButtons.keySet())
-        setButtonEnabled(tool,enabled,hideOnDisable);
-    }   
-    
-    /**
-     * Returns the maximum ID of actions. 
-     */
-    public int getMaxActionID() {
-      return actionButtons.lastKey();
-    }
+	/**
+	 * Sets the activation for all actions.
+	 * 
+	 * @param enabled
+	 *            if {@code true} all actions becomes available
+	 * @param hideOnDisable
+	 *            if {@code true} the buttons are also hidden if {@code enabled}
+	 *            is {@code false}
+	 */
+	public void setAllActionsEnabled(boolean enabled, boolean hideOnDisable) {
+		for (int tool : actionButtons.keySet())
+			setButtonEnabled(tool, enabled, hideOnDisable);
+	}
 
-    /**
-     * Returns the minimum ID of actions. 
-     */
-    public int getMinActionID() {
-      return actionButtons.firstKey();
-    }
-    
-    protected static String getResourceString(String key, Object... params) {
-      return GeotoolsGUIUtil.RESOURCE.getString("schmitzm.geotools.gui.JMapEditorToolBar."+key,params);
-    }
-    
-    /**
-     * Extends the {@link AbstractAction} with maintaining an ID and
-     * the {@link JMapEditorToolBar} the action controls.
-     * Additionally this class automatically calls
-     * {@link JMapEditorToolBar#performActionButton(int, ActionEvent)}.
-     * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
-     */
-    public static class EditorPaneToolBarAction extends AbstractAction {
-      /** The ID of the action */
-      protected int id = -1;
-      /** The tool bar, this action is made for. */
-      protected JMapEditorToolBar toolBar = null;
+	/**
+	 * Returns the maximum ID of actions.
+	 */
+	public int getMaxActionID() {
+		return actionButtons.lastKey();
+	}
 
-      /**
-       * Creates a new action with a dummy description and no icon.
-       * @param id      unique ID for the action
-       * @param toolBar toolbar this action is made for
-       */
-      public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar) {
-        this(id,toolBar,""+id);
-      }
+	/**
+	 * Returns the minimum ID of actions.
+	 */
+	public int getMinActionID() {
+		return actionButtons.firstKey();
+	}
 
-      /**
-       * Creates a new action without an icon.
-       * @param id      unique ID for the action
-       * @param toolBar toolbar this action is made for
-       * @param name    description used for buttons or menus 
-       */
-      public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar, String name) {
-        this(id,toolBar,name,null);
-      }
+	protected static String getResourceString(String key, Object... params) {
+		return GeotoolsGUIUtil.RESOURCE.getString(
+				"schmitzm.geotools.gui.JMapEditorToolBar." + key, params);
+	}
 
-      /**
-       * Creates a new action.
-       * @param id      unique ID for the action
-       * @param toolBar toolbar this action is made for
-       * @param name    description used for buttons or menus 
-       * @param icon    icon used for buttons or menus 
-       */
-      public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar, String name, Icon icon) {
-        super("",icon);
-        this.id      = id;
-        this.toolBar = toolBar;
-        this.putValue(SHORT_DESCRIPTION, getResourceString(name));
-      }
+	/**
+	 * Extends the {@link AbstractAction} with maintaining an ID and the
+	 * {@link JMapEditorToolBar} the action controls. Additionally this class
+	 * automatically calls
+	 * {@link JMapEditorToolBar#performActionButton(int, ActionEvent)}.
+	 * 
+	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+	 *         (University of Bonn/Germany)
+	 */
+	public static class EditorPaneToolBarAction extends AbstractAction {
+		/** The ID of the action */
+		protected int id = -1;
+		/** The tool bar, this action is made for. */
+		protected JMapEditorToolBar toolBar = null;
 
-      /**
-       * Calls {@link JMapEditorToolBar#performActionButton(int, ActionEvent)}.
-       */
-      public void actionPerformed(ActionEvent e) {
-        if ( toolBar.actionButtons.get(id) != null )
-          toolBar.performActionButton(id, e);
-      }
-      
-      /**
-       * Returns the (unique) id of this action.
-       * @return
-       */
-      public int getID() {
-        return id;
-      }
-    }
+		/**
+		 * Creates a new action with a dummy description and no icon.
+		 * 
+		 * @param id
+		 *            unique ID for the action
+		 * @param toolBar
+		 *            toolbar this action is made for
+		 */
+		public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar) {
+			this(id, toolBar, "" + id);
+		}
+
+		/**
+		 * Creates a new action without an icon.
+		 * 
+		 * @param id
+		 *            unique ID for the action
+		 * @param toolBar
+		 *            toolbar this action is made for
+		 * @param name
+		 *            description used for buttons or menus
+		 */
+		public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar,
+				String name) {
+			this(id, toolBar, name, null);
+		}
+
+		/**
+		 * Creates a new action.
+		 * 
+		 * @param id
+		 *            unique ID for the action
+		 * @param toolBar
+		 *            toolbar this action is made for
+		 * @param name
+		 *            description used for buttons or menus
+		 * @param icon
+		 *            icon used for buttons or menus
+		 */
+		public EditorPaneToolBarAction(int id, JMapEditorToolBar toolBar,
+				String name, Icon icon) {
+			super("", icon);
+			this.id = id;
+			this.toolBar = toolBar;
+			this.putValue(SHORT_DESCRIPTION, getResourceString(name));
+		}
+
+		/**
+		 * Calls {@link JMapEditorToolBar#performActionButton(int, ActionEvent)}
+		 * .
+		 */
+		public void actionPerformed(ActionEvent e) {
+			if (toolBar.actionButtons.get(id) != null)
+				toolBar.performActionButton(id, e);
+		}
+
+		/**
+		 * Returns the (unique) id of this action.
+		 * 
+		 * @return
+		 */
+		public int getID() {
+			return id;
+		}
+	}
 }

Modified: branches/2.3.x/src/schmitzm/geotools/gui/LayeredMapFrame.java
===================================================================
--- branches/2.3.x/src/schmitzm/geotools/gui/LayeredMapFrame.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/schmitzm/geotools/gui/LayeredMapFrame.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -80,197 +80,213 @@
  * </ul>
  * Um Layer einzufuegen koennen die {@code addLayer(.)}-Methoden des
  * {@link #getLayeredMapPane() LayeredMapPane} (dabei wird ein Default-Style
- * verwendet) oder die entsprechenden Methoden des {@link MapContext} ({@code
- * getLayeredMapPane().getMapPane().getContext()}).
+ * verwendet) oder die entsprechenden Methoden des {@link MapContext} (
+ * {@code getLayeredMapPane().getMapPane().getContext()}).
+ * 
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
  *         (University of Bonn/Germany)
  * @version 1.0
  */
 public class LayeredMapFrame extends JFrame {
-  private JPanel contentPane = null;
-  /** Karten- und Layer-Kontroll-Bereich. */
-  protected LayeredMapPane layeredMapPane = null;
-  private SelectableXMapPane mapPane = null;
-  private MapContext mapContext = null;
-  /** Toolbar zur Kontroller der Karten-Aktionen (z.B. Zoom oder Select). */
-  protected MapActionControlPane mapControl = null;
-  /** Status-Balken. */
-  protected MapPaneStatusBar statusBar = null;
-  /** Fenster fuer SimpleFeature-Details */
-  protected FeatureCollectionFrame featuresFrame = null;
-  /**
-   * Auswahlfeld fuer das Raster, fuer welches die Koordinaten angezeigt werden.
-   */
-  protected SelectionInputOption<MapLayer> rasterComboBox = null;
+	private JPanel contentPane = null;
+	/** Karten- und Layer-Kontroll-Bereich. */
+	protected LayeredMapPane layeredMapPane = null;
+	private SelectableXMapPane mapPane = null;
+	private MapContext mapContext = null;
+	/** Toolbar zur Kontroller der Karten-Aktionen (z.B. Zoom oder Select). */
+	protected MapActionControlPane mapControl = null;
+	/** Status-Balken. */
+	protected MapPaneStatusBar statusBar = null;
+	/** Fenster fuer SimpleFeature-Details */
+	protected FeatureCollectionFrame featuresFrame = null;
+	/**
+	 * Auswahlfeld fuer das Raster, fuer welches die Koordinaten angezeigt
+	 * werden.
+	 */
+	protected SelectionInputOption<MapLayer> rasterComboBox = null;
 
-  /**
-   * Erzeugt ein neues (leeres) Map-Fenster.
-   */
-  public LayeredMapFrame() {
-    this(null, "");
-  }
+	/**
+	 * Erzeugt ein neues (leeres) Map-Fenster.
+	 */
+	public LayeredMapFrame() {
+		this(null, "");
+	}
 
-  /**
-   * Erzeugt ein neues (leeres) Map-Fenster.
-   * @param lmp {@link LayeredMapPane} welches zur Anzeige der Karten verwendet
-   *          wird (wenn {@code null} wird eine neue {@link LayeredMapPane}
-   *          -Instanz erzeugt)
-   */
-  public LayeredMapFrame(LayeredMapPane lmp) {
-    this(lmp, "");
-  }
+	/**
+	 * Erzeugt ein neues (leeres) Map-Fenster.
+	 * 
+	 * @param lmp
+	 *            {@link LayeredMapPane} welches zur Anzeige der Karten
+	 *            verwendet wird (wenn {@code null} wird eine neue
+	 *            {@link LayeredMapPane} -Instanz erzeugt)
+	 */
+	public LayeredMapFrame(LayeredMapPane lmp) {
+		this(lmp, "");
+	}
 
-  /**
-   * Erzeugt ein neues (leeres) Map-Fenster.
-   * @param title Titel des Fensters
-   */
-  public LayeredMapFrame(String title) {
-    this(null, title);
-  }
+	/**
+	 * Erzeugt ein neues (leeres) Map-Fenster.
+	 * 
+	 * @param title
+	 *            Titel des Fensters
+	 */
+	public LayeredMapFrame(String title) {
+		this(null, title);
+	}
 
-  /**
-   * Erzeugt ein neues (leeres) Map-Fenster.
-   * @param title Titel des Fensters
-   * @param lmp {@link LayeredMapPane} welches zur Anzeige der Karten verwendet
-   *          wird (wenn {@code null} wird eine neue {@link LayeredMapPane}
-   *          -Instanz erzeugt)
-   */
-  public LayeredMapFrame(LayeredMapPane lmp, String title) {
-    super();
-    this.setSize(new Dimension(500, 400));
-    this.setTitle(title);
-    contentPane = (JPanel) this.getContentPane();
-    contentPane.setLayout(new GridBagLayout());
+	/**
+	 * Ausgewaehlte Features werden im Detail-Frame angezeigt. Eine Referenz auf
+	 * diesen Listener muss bestehen, sonst wird er automatisch entfernt.
+	 */
+	JMapPaneListener listenSelectedFeaturesAreShownInDetail = new JMapPaneListener() {
+		public void performMapPaneEvent(XMapPaneEvent e) {
+			// Wenn Features ueber die Maus aus der Karte ausgewaehlt werden,
+			// oeffnet sich ein Detail-Fenster
+			if (e instanceof FeatureSelectedEvent
+					&& e.getSourceObject() == mapPane) {
+				FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
+				FeatureCollection fc = fse.getSelectionResult();
+				featuresFrame.setFeatureCollection(fc);
+				featuresFrame.setTitle(fse.getSourceLayer().getTitle() + " ["
+						+ fse.getSelectionRange() + "]");
+				if (!featuresFrame.isVisible()) {
+					SwingUtil.setRelativeFramePosition(featuresFrame, 1, 0);
+				}
+				featuresFrame.setVisible(true);
+			}
 
-    // Karte und Layer-Kontrolle
-    layeredMapPane = lmp != null ? lmp : new LayeredMapPane();
-    mapPane = layeredMapPane.getMapPane();
-    mapContext = mapPane.getMapContext();
-    mapControl = new MapActionControlPane(mapPane, MapActionControlPane.VERTICAL);
-    mapControl.setFloatable(false);
+			if (e instanceof GridCoverageSelectedEvent) {
+				// ...
+			}
+		}
+	};
 
-    // unter Layer-Liste eine ComboBox mit Raster-Auswahl einfuegen
-    this.rasterComboBox = new SelectionInputOption.Combo<MapLayer>("", false);
-    this.mapContext.addMapLayerListListener(new MapLayerListListener() {
-      public void layerChanged(MapLayerListEvent e) {
-        updateRasterComboBox();
-      }
+	/**
+	 * Erzeugt ein neues (leeres) Map-Fenster.
+	 * 
+	 * @param title
+	 *            Titel des Fensters
+	 * @param lmp
+	 *            {@link LayeredMapPane} welches zur Anzeige der Karten
+	 *            verwendet wird (wenn {@code null} wird eine neue
+	 *            {@link LayeredMapPane} -Instanz erzeugt)
+	 */
+	public LayeredMapFrame(LayeredMapPane lmp, String title) {
+		super();
+		this.setSize(new Dimension(500, 400));
+		this.setTitle(title);
+		contentPane = (JPanel) this.getContentPane();
+		contentPane.setLayout(new GridBagLayout());
 
-      public void layerMoved(MapLayerListEvent e) {
-      }
+		// Karte und Layer-Kontrolle
+		layeredMapPane = lmp != null ? lmp : new LayeredMapPane();
+		mapPane = layeredMapPane.getMapPane();
+		mapContext = mapPane.getMapContext();
+		mapControl = new MapActionControlPane(mapPane,
+				MapActionControlPane.VERTICAL);
+		mapControl.setFloatable(false);
 
-      public void layerAdded(MapLayerListEvent e) {
-        updateRasterComboBox();
-      }
+		// unter Layer-Liste eine ComboBox mit Raster-Auswahl einfuegen
+		this.rasterComboBox = new SelectionInputOption.Combo<MapLayer>("",
+				false);
+		this.mapContext.addMapLayerListListener(new MapLayerListListener() {
+			public void layerChanged(MapLayerListEvent e) {
+				updateRasterComboBox();
+			}
 
-      public void layerRemoved(MapLayerListEvent e) {
-        updateRasterComboBox();
-      }
-    });
-    this.layeredMapPane.horSplitPane.getContainer(0).add(rasterComboBox,
-                                                         BorderLayout.SOUTH);
+			public void layerMoved(MapLayerListEvent e) {
+			}
 
-    // Spezielles RasterPositionLabel in dem die Koordinaten des in der
-    // ComboBox ausgewaehlten Rasters angezeigt werden
-    RasterPositionLabel rpLabel = new RasterPositionLabel(1) {
-      protected MapLayer determineRasterLayer(final SelectableXMapPane mapPane) {
-        return rasterComboBox.getValue();
-      }
-    };
+			public void layerAdded(MapLayerListEvent e) {
+				updateRasterComboBox();
+			}
 
-    // Status-Zeile mit Raster-Auswahlfeld
-    statusBar = new MapPaneStatusBar(mapPane, rpLabel, null);
-    statusBar.setBorder(BorderFactory.createCompoundBorder(
-                                                           BorderFactory.createLoweredBevelBorder(),
-                                                           BorderFactory.createEmptyBorder(
-                                                                                           2,
-                                                                                           5,
-                                                                                           2,
-                                                                                           5)));
+			public void layerRemoved(MapLayerListEvent e) {
+				updateRasterComboBox();
+			}
+		});
+		this.layeredMapPane.horSplitPane.getContainer(0).add(rasterComboBox,
+				BorderLayout.SOUTH);
 
-    // Status-Zeile mit Raster-Auswahlfeld kombinieren
-    JPanel statusBarContainer = new JPanel();
-    statusBarContainer.setLayout(new BorderLayout());
-    statusBarContainer.add(rasterComboBox, BorderLayout.WEST);
-    statusBarContainer.add(statusBar, BorderLayout.CENTER);
+		// Spezielles RasterPositionLabel in dem die Koordinaten des in der
+		// ComboBox ausgewaehlten Rasters angezeigt werden
+		RasterPositionLabel rpLabel = new RasterPositionLabel(1) {
+			protected MapLayer determineRasterLayer(
+					final SelectableXMapPane mapPane) {
+				return rasterComboBox.getValue();
+			}
+		};
 
-    // Root-SplitPane in Fenster einfuegen
-    contentPane.add(layeredMapPane, new GridBagConstraints(0, 0, 1, 1, 1.0,
-        1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,
-            0, 0, 0), 0, 0));
-    contentPane.add(mapControl, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
-        GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 0, 0,
-            0), 0, 0));
-    contentPane.add(statusBarContainer, new GridBagConstraints(0, 1, 2, 1, 1.0,
-        0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2,
-            0, 0, 0), 0, 0));
+		// Status-Zeile mit Raster-Auswahlfeld
+		statusBar = new MapPaneStatusBar(mapPane, rpLabel, null);
+		statusBar.setBorder(BorderFactory.createCompoundBorder(
+				BorderFactory.createLoweredBevelBorder(),
+				BorderFactory.createEmptyBorder(2, 5, 2, 5)));
 
-    // Fenster fuer SimpleFeature-Details
-    featuresFrame = new FeatureCollectionFrame(null, true);
-    featuresFrame.setSize(new Dimension(400, 200));
-    // Ausgewaehlte Features werden im Detail-Frame angezeigt
-    mapPane.addMapPaneListener(new JMapPaneListener() {
-      public void performMapPaneEvent(XMapPaneEvent e) {
-        // Wenn Features ueber die Maus aus der Karte ausgewaehlt werden,
-        // oeffnet sich ein Detail-Fenster
-        if (e instanceof FeatureSelectedEvent && e.getSourceObject() == mapPane) {
-          FeatureSelectedEvent fse = (FeatureSelectedEvent) e;
-          FeatureCollection fc = fse.getSelectionResult();
-          featuresFrame.setFeatureCollection(fc);
-          featuresFrame.setTitle(fse.getSourceLayer().getTitle() + " [" +
-                                 fse.getSelectionRange() + "]");
-          if (!featuresFrame.isVisible()) {
-            SwingUtil.setRelativeFramePosition(featuresFrame, 1, 0);
-          }
-          featuresFrame.setVisible(true);
-        }
+		// Status-Zeile mit Raster-Auswahlfeld kombinieren
+		JPanel statusBarContainer = new JPanel();
+		statusBarContainer.setLayout(new BorderLayout());
+		statusBarContainer.add(rasterComboBox, BorderLayout.WEST);
+		statusBarContainer.add(statusBar, BorderLayout.CENTER);
 
-        if (e instanceof GridCoverageSelectedEvent) {
-          // ...
-        }
-      }
-    });
-  }
+		// Root-SplitPane in Fenster einfuegen
+		contentPane.add(layeredMapPane, new GridBagConstraints(0, 0, 1, 1, 1.0,
+				1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(0, 0, 0, 0), 0, 0));
+		contentPane.add(mapControl, new GridBagConstraints(1, 0, 1, 1, 0.0,
+				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(2, 0, 0, 0), 0, 0));
+		contentPane.add(statusBarContainer, new GridBagConstraints(0, 1, 2, 1,
+				1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(2, 0, 0, 0), 0, 0));
 
-  protected void updateRasterComboBox() {
-    // Letzte Auswahl merken
-    MapLayer lastSelection = (MapLayer) rasterComboBox.getValue();
-    // Alle Raster-Layer und Titel ermitteln
-    Vector<MapLayer> rasterLayer = new Vector<MapLayer>();
-    Vector<String> rasterLayerDesc = new Vector<String>();
-    for (MapLayer layer : mapPane.getMapContext().getLayers())
-      if (mapPane.isGridCoverageLayer(layer)) {
-        rasterLayer.add(layer);
-        rasterLayerDesc.add(layer.getTitle());
-      }
-    // Auswahl neu setzen
-    rasterComboBox.setSelectionObjects(rasterLayer.toArray(new MapLayer[0]),
-                                       rasterLayerDesc.toArray());
-    // Wenn nur ein Raster zur Verfuegung steht, dieses autom. auswaehlen
-    if (rasterLayer.size() == 1)
-      lastSelection = rasterLayer.firstElement();
-    // Letzte Auswahl setzen
-    rasterComboBox.setSelectedItem(lastSelection);
-  }
+		// Fenster fuer SimpleFeature-Details
+		featuresFrame = new FeatureCollectionFrame(null, true);
+		featuresFrame.setSize(new Dimension(400, 200));
 
-  /**
-   * Liefert den Karten- und Kontroll-Bereich des Fensters.
-   */
-  public LayeredMapPane getLayeredMapPane() {
-    return this.layeredMapPane;
-  }
+		mapPane.addMapPaneListenerNew(listenSelectedFeaturesAreShownInDetail);
+	}
 
-  /**
-   * Liefert den Status-Bereich des Fensters.
-   */
-  public MapPaneStatusBar getStatusBar() {
-    return this.statusBar;
-  }
+	protected void updateRasterComboBox() {
+		// Letzte Auswahl merken
+		MapLayer lastSelection = (MapLayer) rasterComboBox.getValue();
+		// Alle Raster-Layer und Titel ermitteln
+		Vector<MapLayer> rasterLayer = new Vector<MapLayer>();
+		Vector<String> rasterLayerDesc = new Vector<String>();
+		for (MapLayer layer : mapPane.getMapContext().getLayers())
+			if (mapPane.isGridCoverageLayer(layer)) {
+				rasterLayer.add(layer);
+				rasterLayerDesc.add(layer.getTitle());
+			}
+		// Auswahl neu setzen
+		rasterComboBox
+				.setSelectionObjects(rasterLayer.toArray(new MapLayer[0]),
+						rasterLayerDesc.toArray());
+		// Wenn nur ein Raster zur Verfuegung steht, dieses autom. auswaehlen
+		if (rasterLayer.size() == 1)
+			lastSelection = rasterLayer.firstElement();
+		// Letzte Auswahl setzen
+		rasterComboBox.setSelectedItem(lastSelection);
+	}
 
-//  /**
-//   * Liefert den Toolbar fuer die Karten-Aktionen.
-//   */
-//  public MapActionControlPane getToolBar() {
-//    return this.mapControl;
-//  }
+	/**
+	 * Liefert den Karten- und Kontroll-Bereich des Fensters.
+	 */
+	public LayeredMapPane getLayeredMapPane() {
+		return this.layeredMapPane;
+	}
+
+	/**
+	 * Liefert den Status-Bereich des Fensters.
+	 */
+	public MapPaneStatusBar getStatusBar() {
+		return this.statusBar;
+	}
+
+	// /**
+	// * Liefert den Toolbar fuer die Karten-Aktionen.
+	// */
+	// public MapActionControlPane getToolBar() {
+	// return this.mapControl;
+	// }
 }

Modified: branches/2.3.x/src/schmitzm/geotools/gui/XMapPane.java
===================================================================
--- branches/2.3.x/src/schmitzm/geotools/gui/XMapPane.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/schmitzm/geotools/gui/XMapPane.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -58,6 +58,7 @@
 import org.geotools.swing.JMapPane;
 import org.geotools.swing.event.MapMouseEvent;
 import org.geotools.swing.event.MapPaneListener;
+import org.geotools.util.WeakHashSet;
 import org.opengis.display.canvas.RenderingState;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
@@ -557,8 +558,17 @@
 	/**
 	 * List of listeners of this {@link XMapPane}
 	 */
-	protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
+	@Deprecated
+	protected Vector<JMapPaneListener> DEPRECATEDmapPaneListeners = new Vector<JMapPaneListener>();
 	/**
+	 * 
+	 * List of {@link JMapPaneListener} for this {@link XMapPane}. The listeners
+	 * are kept in a {@link WeakHashSet}, so calsses listening has to keep a
+	 * reference to the listener or it will be removed.
+	 */
+	protected WeakHashSet<JMapPaneListener> mapPaneListeners = new WeakHashSet<JMapPaneListener>(
+			JMapPaneListener.class);
+	/**
 	 * If not <code>null</code>, the {@link XMapPane} will not allow to zoom/pan
 	 * out of that area
 	 **/
@@ -809,6 +819,8 @@
 	 *            Ereignis
 	 */
 	public void fireMapPaneEvent(XMapPaneEvent e) {
+		for (JMapPaneListener l : DEPRECATEDmapPaneListeners)
+			l.performMapPaneEvent(e);
 		for (JMapPaneListener l : mapPaneListeners)
 			l.performMapPaneEvent(e);
 	}
@@ -818,8 +830,19 @@
 	 * 
 	 * @param l
 	 *            neuer Listener
+	 * @Deprecated Use addMapPaneListenerNew and KEEP A REFERENCE TO THE
+	 *             LISTENER or it will be removed automatically.
 	 */
 	public void addMapPaneListener(final JMapPaneListener l) {
+		DEPRECATEDmapPaneListeners.add(l);
+	}
+
+	/**
+	 * Fuegt der Map einen Listener hinzu. The listenrs do not have to be
+	 * removed. When the listener is not referenced anymore outside, it will be
+	 * removed automatically.
+	 */
+	public void addMapPaneListenerNew(final JMapPaneListener l) {
 		mapPaneListeners.add(l);
 	}
 
@@ -1079,7 +1102,7 @@
 		disposeImages();
 
 		// Remove all mapPaneListeners that have registered with us
-		mapPaneListeners.clear();
+		DEPRECATEDmapPaneListeners.clear();
 
 		removeMouseMotionListener(xMapPaneMouseListener);
 		removeMouseListener(xMapPaneMouseListener);
@@ -1678,7 +1701,7 @@
 
 	@Override
 	protected void paintComponent(final Graphics g) {
-		
+
 		setBackground(Color.blue);
 
 		// Maybe update the cursor and maybe stop the repainting timer
@@ -1689,16 +1712,7 @@
 
 		if (!isWellDefined())
 			return;
-		//
-		// if (paneResized) {
-		// // ((Graphics2D) g).setBackground(getMapBackgroundColor());
-		// // g.clearRect(0, 0, getMapPaneSize().width,
-		// getMapPaneSize().height);
-		// return;
-		// }
 
-		// super.paintComponent(g); // candidate for removal
-
 		boolean paintedSomething = false;
 
 		if (mapImageInvalid) { /* if the map changed then redraw */
@@ -1715,14 +1729,7 @@
 
 				mapAreaChanged = false;
 
-				// if (getMapArea().covers(oldMapArea)) {
-				// // quickPreviewHint = ZOOM_OUT;
-				// paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D)
-				// g);
-				// } else if (oldMapArea.covers(getMapArea())) {
-				// quickPreviewHint = ZOOM_IN;
 				paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);
-				// }
 			}
 		}
 
@@ -1759,15 +1766,6 @@
 	 */
 	private void disposeImages() {
 
-		// System.out.println("vorher = "
-		// + new MbDecimalFormatter().format(LangUtil.gcTotal()));
-		// bi.flush();
-		// return bi = null;
-		// System.out.println("nacher = "
-		// + new MbDecimalFormatter().format(LangUtil.gcTotal()));
-		//
-		// System.out.println("\n");
-
 		if (preFinalImage != null) {
 			preFinalImage.flush();
 			preFinalImage = null;
@@ -1791,46 +1789,17 @@
 
 	}
 
-	//
-	// /**
-	// * Performs a {@value #PAN} action. During panning, the displacement is
-	// * stored in {@link #imageOrigin} object. Calling {@link #performPan()}
-	// will
-	// * reset the offset and call {@link #setMapArea(Envelope)}.
-	// */
-	// public void performPan() {
-	//
-	// final Rectangle winBounds = getMapPaneSize();
-	//
-	// winBounds.translate(-imageOrigin.x, -imageOrigin.y);
-	// final Envelope newMapArea = tranformWindowToGeo(winBounds.x,
-	// winBounds.y, winBounds.x + winBounds.width, winBounds.y
-	// + winBounds.height);
-	//
-	// imageOrigin.x = 0;
-	// imageOrigin.y = 0;
-	//
-	// if (!setMapArea(newMapArea)) {
-	// /**
-	// * If setMapArea returns true, the finalImage is updated anyways.
-	// * This if-case exists to ensure that we repaint a correct image
-	// * even if the new panning area has been denied.
-	// */
-	// updateFinalImage();
-	// repaint();
-	// }
-	//
-	// if (getCursor() == SwingUtil.PANNING_CURSOR)
-	// setCursor(SwingUtil.PAN_CURSOR);
-	// }
-
 	/**
-	 * Entfernt einen Listener von der Map.
+	 * Entfernt einen Listener von der {@link XMapPane}.
 	 * 
 	 * @param l
 	 *            zu entfernender Listener
+	 * 
+	 * @Deprecated Use addMapPaneListenerNew and KEEP A REFERENCE TO THE
+	 *             LISTENER or it will be removed automatically.
 	 */
 	public void removeMapPaneListener(final JMapPaneListener l) {
+		DEPRECATEDmapPaneListeners.remove(l);
 		mapPaneListeners.remove(l);
 	}
 

Modified: branches/2.3.x/src/skrueger/geotools/CrsLabel.java
===================================================================
--- branches/2.3.x/src/skrueger/geotools/CrsLabel.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/skrueger/geotools/CrsLabel.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -23,7 +23,7 @@
 		super();
 		this.mapPane = mapPane;
 
-		mapPane.addMapPaneListener(listenForCrsChange);
+		mapPane.addMapPaneListenerNew(listenForCrsChange);
 
 		updateCrs();
 

Modified: branches/2.3.x/src/skrueger/geotools/MapPaneToolBar.java
===================================================================
--- branches/2.3.x/src/skrueger/geotools/MapPaneToolBar.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/skrueger/geotools/MapPaneToolBar.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -265,13 +265,6 @@
 		init();
 	}
 
-//	private CrsLabel getCrsComponent() {
-//		if (crsViewer == null) {
-//			crsViewer = new CrsLabel(this.mapPane);
-//		}
-//		return crsViewer;
-//	}
-
 	/**
 	 * Sets the {@link SelectableXMapPane} controlled by this tool bar.
 	 * 
@@ -285,7 +278,7 @@
 			this.mapPane.removeMapPaneListener(mapPaneListener);
 		this.mapPane = mapPane;
 		if (this.mapPane != null && mapPaneListener != null)
-			this.mapPane.addMapPaneListener(mapPaneListener);
+			this.mapPane.addMapPaneListenerNew(mapPaneListener);
 	}
 
 	/**

Modified: branches/2.3.x/src/skrueger/geotools/labelsearch/SearchResultFeature.java
===================================================================
--- branches/2.3.x/src/skrueger/geotools/labelsearch/SearchResultFeature.java	2010-12-17 23:08:37 UTC (rev 1353)
+++ branches/2.3.x/src/skrueger/geotools/labelsearch/SearchResultFeature.java	2010-12-18 21:58:10 UTC (rev 1354)
@@ -75,6 +75,23 @@
 		return title;
 	}
 
+	JMapPaneListener listenWhenRenderingIsFInishedAndBlink = new JMapPaneListener() {
+
+//		boolean virgin = true;
+
+		@Override
+		public void performMapPaneEvent(XMapPaneEvent e) {
+			if (e instanceof MapRenderingStateEvent) {
+				MapRenderingStateEvent mre = (MapRenderingStateEvent) e;
+				if (mre.getState() == RenderingState.ON_HOLD) {
+					// Remove this listener, and blink!
+					mapPane.blink(feature);
+					mapPane.removeMapPaneListener(this);
+				}
+			}
+		}
+	};
+
 	@Override
 	public void open() {
 
@@ -86,23 +103,8 @@
 
 		// ZOmming will take some time, until the new map is correctly rendered
 		if (mapPane.zoomTo(feature)) {
-			mapPane.addMapPaneListener(new JMapPaneListener() {
 
-				boolean virgin = true;
-
-				@Override
-				public void performMapPaneEvent(XMapPaneEvent e) {
-					if (virgin && e instanceof MapRenderingStateEvent) {
-						MapRenderingStateEvent mre = (MapRenderingStateEvent) e;
-						if (mre.getState() == RenderingState.ON_HOLD) {
-							// Remove this listener, and blink!
-							mapPane.blink(feature);
-							virgin = false;
-							// mapPane.removeMapPaneListener(this);
-						}
-					}
-				}
-			});
+			mapPane.addMapPaneListenerNew(listenWhenRenderingIsFInishedAndBlink);
 			// TODO Remove the listener and the virgin flag again! otherwise the
 			// listener is never removed!
 		} else {



More information about the Schmitzm-commits mailing list