Revision: 4592
          http://sourceforge.net/p/jump-pilot/code/4592
Author:   edso
Date:     2015-12-08 19:00:14 +0000 (Tue, 08 Dec 2015)
Log Message:
-----------
bugfix #403 "Make layer editable from AttributeTable..."
moved editable, selectable, readonly attributes into the Layerable interface, 
in order to 
- make EditablePlugin handle all Layerables
- make Layerables editable etc. in the future

Modified Paths:
--------------
    
core/trunk/src/com/vividsolutions/jump/workbench/model/AbstractLayerable.java
    core/trunk/src/com/vividsolutions/jump/workbench/model/Layer.java
    core/trunk/src/com/vividsolutions/jump/workbench/model/Layerable.java
    core/trunk/src/com/vividsolutions/jump/workbench/ui/AttributeTab.java
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/EditablePlugIn.java

Modified: 
core/trunk/src/com/vividsolutions/jump/workbench/model/AbstractLayerable.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/workbench/model/AbstractLayerable.java   
    2015-12-08 18:57:03 UTC (rev 4591)
+++ 
core/trunk/src/com/vividsolutions/jump/workbench/model/AbstractLayerable.java   
    2015-12-08 19:00:14 UTC (rev 4592)
@@ -40,147 +40,199 @@
  * @see Layerable
  */
 public abstract class AbstractLayerable implements Layerable {
-    private LayerManager layerManager;
+  private LayerManager layerManager;
 
-    private String name;
+  private String name;
 
-    private boolean visible = true;
+  private boolean visible = true;
+  private boolean editable = false;
+  private boolean selectable = true;
+  private boolean readonly = false;
 
-    private boolean scaleDependentRenderingEnabled = false;
+  private boolean scaleDependentRenderingEnabled = false;
 
-    // When working with scale, the max is less than the min. [Jon Aquino
-    // 2005-03-01]
-    private Double minScale = null;
+  // When working with scale, the max is less than the min. [Jon Aquino
+  // 2005-03-01]
+  private Double minScale = null;
 
-    private Double maxScale = null;
+  private Double maxScale = null;
 
-    /**
-     * Called by Java2XML
-     */
-    public AbstractLayerable() {
-    }
+  /**
+   * Called by Java2XML
+   */
+  public AbstractLayerable() {
+  }
 
-    public AbstractLayerable(String name, LayerManager layerManager) {
-        Assert.isTrue(name != null);
-        Assert.isTrue(layerManager != null);
-        setLayerManager(layerManager);
+  public AbstractLayerable(String name, LayerManager layerManager) {
+    Assert.isTrue(name != null);
+    Assert.isTrue(layerManager != null);
+    setLayerManager(layerManager);
 
-        //Can't fire events because this Layerable hasn't been added to the
-        //LayerManager yet. [Jon Aquino]
-        boolean firingEvents = layerManager.isFiringEvents();
-        layerManager.setFiringEvents(false);
+    // Can't fire events because this Layerable hasn't been added to the
+    // LayerManager yet. [Jon Aquino]
+    boolean firingEvents = layerManager.isFiringEvents();
+    layerManager.setFiringEvents(false);
 
-        try {
-            setName(layerManager.uniqueLayerName(name));
-        } finally {
-            layerManager.setFiringEvents(firingEvents);
-        }
+    try {
+      setName(layerManager.uniqueLayerName(name));
+    } finally {
+      layerManager.setFiringEvents(firingEvents);
     }
+  }
 
-    public void setLayerManager(LayerManager layerManager) {
-        this.layerManager = layerManager;
-    }
+  public void setLayerManager(LayerManager layerManager) {
+    this.layerManager = layerManager;
+  }
 
-    public LayerManager getLayerManager() {
-        return layerManager;
+  public LayerManager getLayerManager() {
+    return layerManager;
+  }
+
+  public void fireLayerChanged(LayerEventType type) {
+    if (getLayerManager() == null) {
+      // layerManager is null when Java2XML creates the object. [Jon
+      // Aquino]
+      return;
     }
 
-    public void fireLayerChanged(LayerEventType type) {
-        if (getLayerManager() == null) {
-            //layerManager is null when Java2XML creates the object. [Jon
-            // Aquino]
-            return;
-        }
+    getLayerManager().fireLayerChanged(this, type);
+  }
 
-        getLayerManager().fireLayerChanged(this, type);
-    }
+  /**
+   * The only time #fireAppearanceChanged must be called is when a party
+   * modifies an attribute of one of the Styles, because Styles don't notify
+   * their layer when they change. But if a party adds or removes a feature, or
+   * applies an EditTransaction to a feature, #fireAppearanceChanged will be
+   * called automatically. This event will be ignored if
+   * LayerManager#isFiringEvents is false
+   */
+  public void fireAppearanceChanged() {
+    fireLayerChanged(LayerEventType.APPEARANCE_CHANGED);
+  }
 
-    /**
-     * The only time #fireAppearanceChanged must be called is when a party
-     * modifies an attribute of one of the Styles, because Styles don't notify
-     * their layer when they change. But if a party adds or removes a feature,
-     * or applies an EditTransaction to a feature, #fireAppearanceChanged will
-     * be called automatically. This event will be ignored if
-     * LayerManager#isFiringEvents is false
-     */
-    public void fireAppearanceChanged() {
-        fireLayerChanged(LayerEventType.APPEARANCE_CHANGED);
-    }
+  public String getName() {
+    return name;
+  }
 
-    public String getName() {
-        return name;
-    }
+  public void setName(String name) {
+    this.name = name;
+    fireLayerChanged(LayerEventType.METADATA_CHANGED);
+  }
 
-    public void setName(String name) {
-        this.name = name;
-        fireLayerChanged(LayerEventType.METADATA_CHANGED);
+  public Task getTask() {
+    if (layerManager != null) {
+      return layerManager.getTask();
+    } else {
+      return null;
     }
+  }
 
-    public Task getTask() {
-      if (layerManager != null) {
-        return layerManager.getTask();
-      } else {
-        return null;
-      }
+  public void setVisible(boolean visible) {
+    if (this.visible == visible) {
+      return;
     }
-    
-    public void setVisible(boolean visible) {
-        if (this.visible == visible) {
-            return;
-        }
 
-        this.visible = visible;
-        fireLayerChanged(LayerEventType.VISIBILITY_CHANGED);
-    }
+    this.visible = visible;
+    fireLayerChanged(LayerEventType.VISIBILITY_CHANGED);
+  }
 
-    //<<TODO:REFACTORING>> Move Visible to LayerSelection, since it should be a
-    // property
-    //of the view, not the model [Jon Aquino]
-    public boolean isVisible() {
-        return visible;
+  /**
+   * Editability is not enforced; all parties are responsible for heeding this
+   * flag.
+   */
+  public void setEditable(boolean editable) {
+    if (this.editable == editable) {
+      return;
     }
 
-    public String toString() {
-        return getName();
-    }
+    this.editable = editable;
+    fireLayerChanged(LayerEventType.METADATA_CHANGED);
+  }
 
-    public Double getMaxScale() {
-        return maxScale;
-    }
+  // <<TODO:REFACTORING>> Move Visible to LayerSelection, since it should be a
+  // property
+  // of the view, not the model [Jon Aquino]
+  public boolean isVisible() {
+    return visible;
+  }
 
-    public Layerable setMaxScale(Double maxScale) {
-        if (LangUtil.bothNullOrEqual(this.maxScale, maxScale)) {
-            return this;
-        }
-        this.maxScale = maxScale;
-        fireAppearanceChanged();
-        return this;
-    }
+  public boolean isEditable() {
+    return editable;
+  }
 
-    public Double getMinScale() {
-        return minScale;
-    }
+  /**
+   * @return true if this layer should always be 'readonly' I.e.: The layer
+   *         should never have the editable field set to true.
+   */
+  public boolean isReadonly() {
+    return readonly;
+  }
 
-    public Layerable setMinScale(Double minScale) {
-        if (LangUtil.bothNullOrEqual(this.minScale, minScale)) {
-            return this;
-        }
-        this.minScale = minScale;
-        fireAppearanceChanged();
-        return this;
+  /**
+   * Set whether this layer can be made editable.
+   */
+  public void setReadonly(boolean value) {
+    readonly = value;
+  }
+
+  /**
+   * @return true if features in this layer can be selected.
+   */
+  public boolean isSelectable() {
+    return selectable;
+  }
+
+  /**
+   * Set whether or not features in this layer can be selected.
+   * 
+   * @param value
+   *          true if features in this layer can be selected
+   */
+  public void setSelectable(boolean value) {
+    selectable = value;
+  }
+
+  public String toString() {
+    return getName();
+  }
+
+  public Double getMaxScale() {
+    return maxScale;
+  }
+
+  public Layerable setMaxScale(Double maxScale) {
+    if (LangUtil.bothNullOrEqual(this.maxScale, maxScale)) {
+      return this;
     }
+    this.maxScale = maxScale;
+    fireAppearanceChanged();
+    return this;
+  }
 
-    public boolean isScaleDependentRenderingEnabled() {
-        return scaleDependentRenderingEnabled;
+  public Double getMinScale() {
+    return minScale;
+  }
+
+  public Layerable setMinScale(Double minScale) {
+    if (LangUtil.bothNullOrEqual(this.minScale, minScale)) {
+      return this;
     }
+    this.minScale = minScale;
+    fireAppearanceChanged();
+    return this;
+  }
 
-    public Layerable setScaleDependentRenderingEnabled(
-            boolean scaleDependentRenderingEnabled) {
-        if (this.scaleDependentRenderingEnabled == 
scaleDependentRenderingEnabled) {
-            return this;
-        }
-        this.scaleDependentRenderingEnabled = scaleDependentRenderingEnabled;
-        fireAppearanceChanged();
-        return this;
+  public boolean isScaleDependentRenderingEnabled() {
+    return scaleDependentRenderingEnabled;
+  }
+
+  public Layerable setScaleDependentRenderingEnabled(
+      boolean scaleDependentRenderingEnabled) {
+    if (this.scaleDependentRenderingEnabled == scaleDependentRenderingEnabled) 
{
+      return this;
     }
+    this.scaleDependentRenderingEnabled = scaleDependentRenderingEnabled;
+    fireAppearanceChanged();
+    return this;
+  }
 }
\ No newline at end of file

Modified: core/trunk/src/com/vividsolutions/jump/workbench/model/Layer.java
===================================================================
--- core/trunk/src/com/vividsolutions/jump/workbench/model/Layer.java   
2015-12-08 18:57:03 UTC (rev 4591)
+++ core/trunk/src/com/vividsolutions/jump/workbench/model/Layer.java   
2015-12-08 19:00:14 UTC (rev 4592)
@@ -64,581 +64,528 @@
  * prefer #addAll and #removeAll to #add and #remove -- fewer events will be
  * fired.
  */
-public class Layer extends AbstractLayerable implements LayerManagerProxy, 
Disposable {
-    
-       public static final String 
FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE = Layer.class
-                       .getName()
-                       + " - FIRING APPEARANCE CHANGED ON ATTRIBUTE CHANGE";
+public class Layer extends AbstractLayerable implements LayerManagerProxy,
+    Disposable {
 
-       private String description = "";
+  public static final String FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE = 
Layer.class
+      .getName() + " - FIRING APPEARANCE CHANGED ON ATTRIBUTE CHANGE";
 
-       private boolean drawingLast = false;
+  private String description = "";
 
-       private FeatureCollectionWrapper featureCollectionWrapper;
+  private boolean drawingLast = false;
 
-       private ArrayList styles = new ArrayList();
+  private FeatureCollectionWrapper featureCollectionWrapper;
 
-       private boolean synchronizingLineColor = true;
+  private ArrayList styles = new ArrayList();
 
-       private boolean editable = false;
+  private boolean synchronizingLineColor = true;
 
-    private boolean selectable = true;
+  private LayerListener layerListener = null;
 
-    private boolean readonly = false;
+  private Blackboard blackboard = new Blackboard() {
+    private static final long serialVersionUID = 6504993615735124204L;
+    {
+      put(FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE, true);
+    }
+  };
 
-       private LayerListener layerListener = null;
+  private boolean featureCollectionModified = false;
 
-       private Blackboard blackboard = new Blackboard() {
-               private static final long serialVersionUID = 
6504993615735124204L;
-               {
-                       put(FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE, 
true);
-               }
-       };
+  private DataSourceQuery dataSourceQuery;
 
-       private boolean featureCollectionModified = false;
+  /**
+   * Called by Java2XML
+   */
+  public Layer() {
+  }
 
-       private DataSourceQuery dataSourceQuery;
+  public Layer(String name, Color fillColor,
+      FeatureCollection featureCollection, LayerManager layerManager) {
+    super(name, layerManager);
+    Assert.isTrue(featureCollection != null);
 
-       /**
-        * Called by Java2XML
-        */
-       public Layer() {
-       }
+    // Can't fire events because this Layerable hasn't been added to the
+    // LayerManager yet. [Jon Aquino]
+    boolean firingEvents = layerManager.isFiringEvents();
+    layerManager.setFiringEvents(false);
 
-       public Layer(String name, Color fillColor,
-                       FeatureCollection featureCollection, LayerManager 
layerManager) {
-               super(name, layerManager);
-               Assert.isTrue(featureCollection != null);
+    try {
+      addStyle(new BasicStyle());
+      addStyle(new SquareVertexStyle());
+      addStyle(new LabelStyle());
+    } finally {
+      layerManager.setFiringEvents(firingEvents);
+    }
 
-               //Can't fire events because this Layerable hasn't been added to 
the
-               //LayerManager yet. [Jon Aquino]
-               boolean firingEvents = layerManager.isFiringEvents();
-               layerManager.setFiringEvents(false);
+    getBasicStyle().setFillColor(fillColor);
+    getBasicStyle().setLineColor(defaultLineColor(fillColor));
+    getBasicStyle().setAlpha(150);
+    getVertexStyle().setFillColor(fillColor);
+    getVertexStyle().setLineColor(defaultLineColor(fillColor));
+    getVertexStyle().setAlpha(150);
+    getVertexStyle().setEnabled(false);
+    setFeatureCollection(featureCollection);
+  }
 
-               try {
-                       addStyle(new BasicStyle());
-                       addStyle(new SquareVertexStyle());
-                       addStyle(new LabelStyle());
-               } finally {
-                       layerManager.setFiringEvents(firingEvents);
-               }
+  /**
+   * @return a darker version of the given fill colour, for use as the line
+   *         colour
+   */
+  public static Color defaultLineColor(Color fillColor) {
+    return fillColor.darker();
+  }
 
-               getBasicStyle().setFillColor(fillColor);
-               getBasicStyle().setLineColor(defaultLineColor(fillColor));
-               getBasicStyle().setAlpha(150);
-        getVertexStyle().setFillColor(fillColor);
-        getVertexStyle().setLineColor(defaultLineColor(fillColor));
-        getVertexStyle().setAlpha(150);
-        getVertexStyle().setEnabled(false);
-               setFeatureCollection(featureCollection);
-       }
+  public void setDescription(String description) {
+    Assert
+        .isTrue(
+            description != null,
+            "Java2XML requires that the description be non-null. Use an empty 
string if necessary.");
+    this.description = description;
+  }
 
-       /**
-        * @return a darker version of the given fill colour, for use as the 
line
-        *         colour
-        */
-       public static Color defaultLineColor(Color fillColor) {
-               return fillColor.darker();
-       }
+  /**
+   * Used for lightweight layers like the Vector layer.
+   *
+   * @param drawingLast
+   *          true if the layer should be among those drawn last
+   */
+  public void setDrawingLast(boolean drawingLast) {
+    this.drawingLast = drawingLast;
+    fireAppearanceChanged();
+  }
 
-       public void setDescription(String description) {
-               Assert.isTrue(
-                                               description != null,
-                                               "Java2XML requires that the 
description be non-null. Use an empty string if necessary.");
-               this.description = description;
-       }
+  public void setFeatureCollection(final FeatureCollection featureCollection) {
+    final FeatureCollection oldFeatureCollection = featureCollectionWrapper != 
null ? featureCollectionWrapper
+        .getUltimateWrappee() : AddNewLayerPlugIn
+        .createBlankFeatureCollection();
+    ObservableFeatureCollection observableFeatureCollection = new 
ObservableFeatureCollection(
+        featureCollection);
+    observableFeatureCollection.checkNotWrappingSameClass();
+    observableFeatureCollection.add(new ObservableFeatureCollection.Listener() 
{
+      public void featuresAdded(Collection features) {
+        getLayerManager().fireFeaturesChanged(features, FeatureEventType.ADDED,
+            Layer.this);
+      }
 
-    /**
-     * @return true if this layer should always be 'readonly' I.e.: The layer
-     * should never have the editable field set to true.
-    */
-    public boolean isReadonly() {
-        return readonly;
-    }
+      public void featuresRemoved(Collection features) {
+        getLayerManager().fireFeaturesChanged(features,
+            FeatureEventType.DELETED, Layer.this);
+      }
+    });
 
-   /**
-    * Set whether this layer can be made editable.
-    */
-    public void setReadonly( boolean value ) {
-        readonly = value;
+    if ((getLayerManager() != null)
+        && getLayerManager().getLayers().contains(this)
+        && getLayerManager().isFiringEvents()) {
+      // Don't fire APPEARANCE_CHANGED immediately, to avoid the
+      // following problem:
+      // (1) Add fence layer
+      // (2) LAYER_ADDED event will be called
+      // (3) APPEARANCE_CHANGED will be fired in this method (before
+      // the JTree receives its LAYER_ADDED event)
+      // (4) The JTree will complain because it gets the
+      // APPEARANCE_CHANGED
+      // event before the LAYER_ADDED event:
+      // java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
+      // at java.util.Vector.elementAt(Vector.java:412)
+      // at
+      // 
javax.swing.tree.DefaultMutableTreeNode.getChildAt(DefaultMutableTreeNode.java:226)
+      // at
+      // 
javax.swing.tree.VariableHeightLayoutCache.treeNodesChanged(VariableHeightLayoutCache.java:369)
+      // at
+      // 
javax.swing.plaf.basic.BasicTreeUI$TreeModelHandler.treeNodesChanged(BasicTreeUI.java:2339)
+      // at
+      // 
javax.swing.tree.DefaultTreeModel.fireTreeNodesChanged(DefaultTreeModel.java:435)
+      // at
+      // 
javax.swing.tree.DefaultTreeModel.nodesChanged(DefaultTreeModel.java:318)
+      // at
+      // 
javax.swing.tree.DefaultTreeModel.nodeChanged(DefaultTreeModel.java:251)
+      // at
+      // 
com.vividsolutions.jump.workbench.model.LayerTreeModel.layerChanged(LayerTreeModel.java:292)
+      // [Jon Aquino]
+      SwingUtilities.invokeLater(new Runnable() {
+        public void run() {
+          // Changed APPEARANCE_CHANGED event to FEATURE_DELETED and
+          // FEATURE_ADDED events, but I think the lengthy comment
+          // above still applies. [Jon Aquino]
+          // Drop #isEmpty checks, so that database-backed feature
+          // collections don't have to implement it.
+          // [Jon Aquino 2005-03-02]
+          getLayerManager().fireFeaturesChanged(
+              oldFeatureCollection.getFeatures(), FeatureEventType.DELETED,
+              Layer.this);
+          getLayerManager().fireFeaturesChanged(
+              featureCollection.getFeatures(), FeatureEventType.ADDED,
+              Layer.this);
+        }
+      });
     }
 
+    setFeatureCollectionWrapper(observableFeatureCollection);
+  }
 
-    /**
-     * @return true if features in this layer can be selected.
-    */
-    public boolean isSelectable() {
-        return selectable;
-    }
+  public void setSynchronizingLineColor(boolean synchronizingLineColor) {
+    this.synchronizingLineColor = synchronizingLineColor;
+    fireAppearanceChanged();
+  }
 
-    /**
-     * Set whether or not features in this layer can be selected.
-     * @param value true if features in this layer can be selected
-    */
-    public void setSelectable( boolean value ) {
-        selectable = value;
-    }
+  public BasicStyle getBasicStyle() {
+    return (BasicStyle) getStyle(BasicStyle.class);
+  }
 
-       /**
-        * Used for lightweight layers like the Vector layer.
-        *
-        * @param drawingLast
-        *            true if the layer should be among those drawn last
-        */
-       public void setDrawingLast(boolean drawingLast) {
-               this.drawingLast = drawingLast;
-               fireAppearanceChanged();
-       }
+  public VertexStyle getVertexStyle() {
+    return (VertexStyle) getStyle(VertexStyle.class);
+  }
 
-       public void setFeatureCollection(final FeatureCollection 
featureCollection) {
-               final FeatureCollection oldFeatureCollection = 
featureCollectionWrapper != null ? featureCollectionWrapper
-                               .getUltimateWrappee()
-                               : 
AddNewLayerPlugIn.createBlankFeatureCollection();
-               ObservableFeatureCollection observableFeatureCollection = new 
ObservableFeatureCollection(
-                               featureCollection);
-               observableFeatureCollection.checkNotWrappingSameClass();
-               observableFeatureCollection
-                               .add(new ObservableFeatureCollection.Listener() 
{
-                                       public void featuresAdded(Collection 
features) {
-                                               
getLayerManager().fireFeaturesChanged(features,
-                                                               
FeatureEventType.ADDED, Layer.this);
-                                       }
+  public LabelStyle getLabelStyle() {
+    return (LabelStyle) getStyle(LabelStyle.class);
+  }
 
-                                       public void featuresRemoved(Collection 
features) {
-                                               
getLayerManager().fireFeaturesChanged(features,
-                                                               
FeatureEventType.DELETED, Layer.this);
-                                       }
-                               });
+  public String getDescription() {
+    return description;
+  }
 
-               if ((getLayerManager() != null)
-                               && getLayerManager().getLayers().contains(this)
-                && getLayerManager().isFiringEvents()) {
-                       //Don't fire APPEARANCE_CHANGED immediately, to avoid 
the
-                       //following problem:
-                       //(1) Add fence layer
-                       //(2) LAYER_ADDED event will be called
-                       //(3) APPEARANCE_CHANGED will be fired in this method 
(before
-                       //the JTree receives its LAYER_ADDED event)
-                       //(4) The JTree will complain because it gets the
-                       // APPEARANCE_CHANGED
-                       //event before the LAYER_ADDED event:
-                       //            java.lang.ArrayIndexOutOfBoundsException: 
0 >= 0
-                       //                at 
java.util.Vector.elementAt(Vector.java:412)
-                       //                at
-                       // 
javax.swing.tree.DefaultMutableTreeNode.getChildAt(DefaultMutableTreeNode.java:226)
-                       //                at
-                       // 
javax.swing.tree.VariableHeightLayoutCache.treeNodesChanged(VariableHeightLayoutCache.java:369)
-                       //                at
-                       // 
javax.swing.plaf.basic.BasicTreeUI$TreeModelHandler.treeNodesChanged(BasicTreeUI.java:2339)
-                       //                at
-                       // 
javax.swing.tree.DefaultTreeModel.fireTreeNodesChanged(DefaultTreeModel.java:435)
-                       //                at
-                       // 
javax.swing.tree.DefaultTreeModel.nodesChanged(DefaultTreeModel.java:318)
-                       //                at
-                       // 
javax.swing.tree.DefaultTreeModel.nodeChanged(DefaultTreeModel.java:251)
-                       //                at
-                       // 
com.vividsolutions.jump.workbench.model.LayerTreeModel.layerChanged(LayerTreeModel.java:292)
-                       //[Jon Aquino]
-                       SwingUtilities.invokeLater(new Runnable() {
-                               public void run() {
-                                       //Changed APPEARANCE_CHANGED event to 
FEATURE_DELETED and
-                                       //FEATURE_ADDED events, but I think the 
lengthy comment
-                                       //above still applies. [Jon Aquino]
-                                       //Drop #isEmpty checks, so that 
database-backed feature
-                                       //collections don't have to implement 
it.
-                                       //[Jon Aquino 2005-03-02]
-                                       getLayerManager().fireFeaturesChanged(
-                                                       
oldFeatureCollection.getFeatures(),
-                                                       
FeatureEventType.DELETED, Layer.this);
-                                       getLayerManager().fireFeaturesChanged(
-                                                       
featureCollection.getFeatures(),
-                                                       FeatureEventType.ADDED, 
Layer.this);
-                               }
-                       });
-               }
-               
-               setFeatureCollectionWrapper(observableFeatureCollection);
-       }
+  /**
+   * Returns a wrapper around the FeatureCollection which was added using
+   * #wrapFeatureCollection. The original FeatureCollection can be retrieved
+   * using FeatureCollectionWrapper#getWrappee. However, parties are encouraged
+   * to use the FeatureCollectionWrapper instead, so that feature additions and
+   * removals cause FeatureEvents to be fired (by the Layer).
+   */
+  public FeatureCollectionWrapper getFeatureCollectionWrapper() {
+    return featureCollectionWrapper;
+  }
 
-       /**
-        * Editability is not enforced; all parties are responsible for heeding 
this
-        * flag.
-        */
-       public void setEditable(boolean editable) {
-               if (this.editable == editable) {
-                       return;
-               }
+  protected void setFeatureCollectionWrapper(
+      FeatureCollectionWrapper featureCollectionWrapper) {
+    this.featureCollectionWrapper = featureCollectionWrapper;
+    // To set FeatureSchema's dynamic attributes (AKA Operations), we need
+    // a reference to the FeatureSchema. This is the reason why it is not
+    // done immediately by the xml2java deserialization but here, after the
+    // FeatureCollection has been set.
+    setFeatureSchemaOperations();
+  }
 
-               this.editable = editable;
-               fireLayerChanged(LayerEventType.METADATA_CHANGED);
-       }
+  /**
+   * Styles do not notify the Layer when their parameters change. Therefore,
+   * after you modify a Style's parameters (for example, the fill colour of
+   * BasicStyle), be sure to call #fireAppearanceChanged
+   *
+   * @param c
+   *          Can even be the desired Style's superclass or interface
+   * @return The style value
+   */
+  public Style getStyle(Class c) {
+    for (Iterator i = styles.iterator(); i.hasNext();) {
+      Style p = (Style) i.next();
 
-       public boolean isEditable() {
-               return editable;
-       }
+      if (c.isInstance(p)) {
+        return p;
+      }
+    }
 
-       public void setSynchronizingLineColor(boolean synchronizingLineColor) {
-               this.synchronizingLineColor = synchronizingLineColor;
-               fireAppearanceChanged();
-       }
+    return null;
+  }
 
-       public BasicStyle getBasicStyle() {
-               return (BasicStyle) getStyle(BasicStyle.class);
-       }
+  /**
+   * get a list of all enabled styles matching the parameter class
+   */
+  public List<Style> getStylesIfEnabled(Class filter) {
+    List<Style> enabledStyles = new ArrayList();
+    final List<Style> someStyles = getStyles(filter);
+    for (Style style : someStyles) {
+      if (((Style) style).isEnabled())
+        enabledStyles.add(style);
+    }
+    return Collections.unmodifiableList(enabledStyles);
+  }
 
-       public VertexStyle getVertexStyle() {
-               return (VertexStyle) getStyle(VertexStyle.class);
-       }
+  /**
+   * get a list of all styles
+   */
+  public List<Style> getStyles() {
+    return Collections.unmodifiableList(styles);
+  }
 
-       public LabelStyle getLabelStyle() {
-               return (LabelStyle) getStyle(LabelStyle.class);
-       }
+  /**
+   * get a list of all styles matching the parameter class
+   */
+  public List<Style> getStyles(Class filter) {
+    List<Style> someStyles = new ArrayList();
+    final Collection<Style> currentStyles = getStyles();
+    for (Style style : currentStyles) {
+      if (style instanceof Style && filter.isInstance(style)) {
+        someStyles.add(style);
+      }
+    }
+    return Collections.unmodifiableList(someStyles);
+  }
 
-       public String getDescription() {
-               return description;
-       }
+  public boolean hasReadableDataSource() {
+    return dataSourceQuery != null
+        && dataSourceQuery.getDataSource().isReadable();
+  }
 
-       /**
-        * Returns a wrapper around the FeatureCollection which was added using
-        * #wrapFeatureCollection. The original FeatureCollection can be 
retrieved
-        * using FeatureCollectionWrapper#getWrappee. However, parties are
-        * encouraged to use the FeatureCollectionWrapper instead, so that 
feature
-        * additions and removals cause FeatureEvents to be fired (by the 
Layer).
-        */
-       public FeatureCollectionWrapper getFeatureCollectionWrapper() {
-               return featureCollectionWrapper;
-       }
+  public boolean isDrawingLast() {
+    return drawingLast;
+  }
 
-       protected void setFeatureCollectionWrapper(
-                       FeatureCollectionWrapper featureCollectionWrapper) {
-               this.featureCollectionWrapper = featureCollectionWrapper;
-               // To set FeatureSchema's dynamic attributes (AKA Operations), 
we need
-               // a reference to the FeatureSchema. This is the reason why it 
is not
-               // done immediately by the xml2java deserialization but here, 
after the 
-               // FeatureCollection has been set.
-               setFeatureSchemaOperations();
-       }
+  public boolean isSynchronizingLineColor() {
+    return synchronizingLineColor;
+  }
 
-       /**
-        * Styles do not notify the Layer when their parameters change. 
Therefore,
-        * after you modify a Style's parameters (for example, the fill colour 
of
-        * BasicStyle), be sure to call #fireAppearanceChanged
-        *
-        * @param c
-        *            Can even be the desired Style's superclass or interface
-        * @return The style value
-        */
-       public Style getStyle(Class c) {
-               for (Iterator i = styles.iterator(); i.hasNext();) {
-                       Style p = (Style) i.next();
+  public void addStyle(Style style) {
+    styles.add(style);
+    fireAppearanceChanged();
+  }
 
-                       if (c.isInstance(p)) {
-                               return p;
-                       }
-               }
+  /**
+   * Releases references to the data, to facilitate garbage collection.
+   * Important for MDI apps like the JUMP Workbench. Called when the last
+   * JInternalFrame viewing the LayerManager is closed (i.e. internal frame's
+   * responsibility). To conserve memory, if layers are frequently added and
+   * removed from the LayerManager, parties may want to call #dispose 
themselves
+   * rather than waiting for the internal frame to be closed.
+   */
+  public void dispose() {
+    // dispose features if disposable nature
+    Collection features = getFeatureCollectionWrapper().getFeatures();
+    for (Iterator iter = features.iterator(); iter.hasNext();) {
+      Feature feature = (Feature) iter.next();
+      if (feature instanceof Disposable)
+        ((Disposable) feature).dispose();
+    }
+    // Don't just call FeatureCollection#removeAll, because it may be a
+    // database table, and we don't want to delete its contents! [Jon Aquino]
+    setFeatureCollection(AddNewLayerPlugIn.createBlankFeatureCollection());
+  }
 
-               return null;
-       }
+  public void removeStyle(Style p) {
+    Assert.isTrue(styles.remove(p));
+    fireAppearanceChanged();
+  }
 
-    /**
-     * get a list of all enabled styles matching the parameter class
-     */
-    public List<Style> getStylesIfEnabled(Class filter) {
-      List<Style> enabledStyles = new ArrayList();
-      final List<Style> someStyles = getStyles(filter);
-      for (Style style : someStyles) {
-          if (((Style) style).isEnabled())
-            enabledStyles.add(style);
-      }
-      return Collections.unmodifiableList(enabledStyles);
-    }
+  public Collection<Style> cloneStyles() {
+    ArrayList<Style> styleClones = new ArrayList<Style>();
 
-    /**
-     * get a list of all styles
-     */
-       public List<Style> getStyles() {
-               return Collections.unmodifiableList(styles);
-       }
-
-    /**
-     * get a list of all styles matching the parameter class
-     */        
-    public List<Style> getStyles(Class filter) {
-      List<Style> someStyles = new ArrayList();
-      final Collection<Style> currentStyles = getStyles();
-      for (Style style : currentStyles) {
-        if (style instanceof Style && filter.isInstance(style)) {
-          someStyles.add(style);
-        }
-      }
-      return Collections.unmodifiableList(someStyles);
+    for (Iterator<Style> i = getStyles().iterator(); i.hasNext();) {
+      Style style = i.next();
+      styleClones.add((Style) style.clone());
     }
 
-       public boolean hasReadableDataSource() {
-               return dataSourceQuery != null
-                               && dataSourceQuery.getDataSource().isReadable();
-       }
+    return styleClones;
+  }
 
-       public boolean isDrawingLast() {
-               return drawingLast;
-       }
+  public void setStyles(Collection newStyles) {
+    boolean firingEvents = getLayerManager().isFiringEvents();
+    getLayerManager().setFiringEvents(false);
 
-       public boolean isSynchronizingLineColor() {
-               return synchronizingLineColor;
-       }
+    try {
+      // new ArrayList to prevent ConcurrentModificationException [Jon
+      // Aquino]
+      for (Iterator i = new ArrayList(getStyles()).iterator(); i.hasNext();) {
+        Style style = (Style) i.next();
+        removeStyle(style);
+      }
 
-       public void addStyle(Style style) {
-               styles.add(style);
-               fireAppearanceChanged();
-       }
-
-    /**
-     * Releases references to the data, to facilitate garbage collection.
-     * Important for MDI apps like the JUMP Workbench. Called when the last
-     * JInternalFrame viewing the LayerManager is closed (i.e. internal frame's
-     * responsibility). To conserve memory, if layers are frequently added and
-     * removed from the LayerManager, parties may want to call #dispose 
themselves
-     * rather than waiting for the internal frame to be closed.
-     */
-    public void dispose() {
-      // dispose features if disposable nature
-      Collection features = getFeatureCollectionWrapper().getFeatures();
-      for (Iterator iter = features.iterator(); iter.hasNext();) {
-        Feature feature = (Feature) iter.next();
-        if (feature instanceof Disposable)
-          ((Disposable)feature).dispose();
+      for (Iterator i = newStyles.iterator(); i.hasNext();) {
+        Style style = (Style) i.next();
+        addStyle(style);
       }
-      // Don't just call FeatureCollection#removeAll, because it may be a
-      // database table, and we don't want to delete its contents! [Jon Aquino]
-      setFeatureCollection(AddNewLayerPlugIn.createBlankFeatureCollection());
+    } finally {
+      getLayerManager().setFiringEvents(firingEvents);
     }
 
-       public void removeStyle(Style p) {
-               Assert.isTrue(styles.remove(p));
-               fireAppearanceChanged();
-       }
+    fireAppearanceChanged();
+  }
 
-       public Collection<Style> cloneStyles() {
-               ArrayList<Style> styleClones = new ArrayList<Style>();
+  public void setLayerManager(LayerManager layerManager) {
+    if (layerManager != null) {
+      layerManager.removeLayerListener(getLayerListener());
+    }
 
-               for (Iterator<Style> i = getStyles().iterator(); i.hasNext();) {
-                       Style style = i.next();
-                       styleClones.add((Style)style.clone());
-               }
+    super.setLayerManager(layerManager);
+    layerManager.addLayerListener(getLayerListener());
+  }
 
-               return styleClones;
-       }
+  private LayerListener getLayerListener() {
+    // Need to create layerListener lazily because it will be called by the
+    // superclass constructor. [Jon Aquino]
+    if (layerListener == null) {
+      layerListener = new LayerListener() {
+        public void featuresChanged(FeatureEvent e) {
+          if (e.getLayer() == Layer.this) {
+            setFeatureCollectionModified(true);
 
-       public void setStyles(Collection newStyles) {
-               boolean firingEvents = getLayerManager().isFiringEvents();
-               getLayerManager().setFiringEvents(false);
+            // Before I wasn't firing appearance-changed on an
+            // attribute
+            // change. But now with labelling and colour theming,
+            // I have to. [Jon Aquino]
+            if (e.getType() != FeatureEventType.ATTRIBUTES_MODIFIED
+                || getBlackboard().get(
+                    FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE, true)) {
+              // Fixed bug above -- wasn't supplying a default
+              // value to
+              // Blackboard#getBoolean, resulting in a
+              // NullPointerException
+              // when the Layer was created using the
+              // parameterless
+              // constructor (because that constructor doesn't
+              // initialize
+              // FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE
+              // on the blackboard [Jon Aquino 10/21/2003]
+              fireAppearanceChanged();
+            }
+          }
+        }
 
-               try {
-                       //new ArrayList to prevent 
ConcurrentModificationException [Jon
-                       // Aquino]
-                       for (Iterator i = new 
ArrayList(getStyles()).iterator(); i
-                                       .hasNext();) {
-                               Style style = (Style) i.next();
-                               removeStyle(style);
-                       }
+        public void layerChanged(LayerEvent e) {
+        }
 
-                       for (Iterator i = newStyles.iterator(); i.hasNext();) {
-                               Style style = (Style) i.next();
-                               addStyle(style);
-                       }
-               } finally {
-                       getLayerManager().setFiringEvents(firingEvents);
-               }
+        public void categoryChanged(CategoryEvent e) {
+        }
+      };
+    }
 
-               fireAppearanceChanged();
-       }
+    return layerListener;
+  }
 
-       public void setLayerManager(LayerManager layerManager) {
-               if (layerManager != null) {
-                       layerManager.removeLayerListener(getLayerListener());
-               }
+  public Blackboard getBlackboard() {
+    return blackboard;
+  }
 
-               super.setLayerManager(layerManager);
-               layerManager.addLayerListener(getLayerListener());
-       }
+  /**
+   * Enables a layer to be changed undoably. Since the layer's features are
+   * saved, only use this method for layers with few features.
+   */
+  public static UndoableCommand addUndo(final String layerName,
+      final LayerManagerProxy proxy, final UndoableCommand wrappeeCommand) {
+    return new UndoableCommand(wrappeeCommand.getName()) {
+      private Layer layer;
 
-       private LayerListener getLayerListener() {
-               //Need to create layerListener lazily because it will be called 
by the
-               //superclass constructor. [Jon Aquino]
-               if (layerListener == null) {
-                       layerListener = new LayerListener() {
-                               public void featuresChanged(FeatureEvent e) {
-                                       if (e.getLayer() == Layer.this) {
-                                               
setFeatureCollectionModified(true);
+      private String categoryName;
 
-                                               //Before I wasn't firing 
appearance-changed on an
-                                               // attribute
-                                               //change. But now with 
labelling and colour theming,
-                                               //I have to. [Jon Aquino]
-                                               if (e.getType() != 
FeatureEventType.ATTRIBUTES_MODIFIED
-                                                               || 
getBlackboard()
-                                                                               
.get(
-                                                                               
                FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE,
-                                                                               
                true)) {
-                                                       //Fixed bug above -- 
wasn't supplying a default
-                                                       // value to
-                                                       
//Blackboard#getBoolean, resulting in a
-                                                       // NullPointerException
-                                                       //when the Layer was 
created using the
-                                                       // parameterless
-                                                       //constructor (because 
that constructor doesn't
-                                                       // initialize
-                                                       
//FIRING_APPEARANCE_CHANGED_ON_ATTRIBUTE_CHANGE
-                                                       //on the blackboard 
[Jon Aquino 10/21/2003]
-                                                       fireAppearanceChanged();
-                                               }
-                                       }
-                               }
+      private Collection features;
 
-                               public void layerChanged(LayerEvent e) {
-                               }
+      private boolean visible;
 
-                               public void categoryChanged(CategoryEvent e) {
-                               }
-                       };
-               }
+      private Layer currentLayer() {
+        return proxy.getLayerManager().getLayer(layerName);
+      }
 
-               return layerListener;
-       }
+      public void execute() {
+        layer = currentLayer();
 
-       public Blackboard getBlackboard() {
-               return blackboard;
-       }
+        if (layer != null) {
+          features = new ArrayList(layer.getFeatureCollectionWrapper()
+              .getFeatures());
+          categoryName = layer.getName();
+          visible = layer.isVisible();
+        }
 
-       /**
-        * Enables a layer to be changed undoably. Since the layer's features 
are
-        * saved, only use this method for layers with few features.
-        */
-       public static UndoableCommand addUndo(final String layerName,
-                       final LayerManagerProxy proxy, final UndoableCommand 
wrappeeCommand) {
-               return new UndoableCommand(wrappeeCommand.getName()) {
-                       private Layer layer;
+        wrappeeCommand.execute();
+      }
 
-                       private String categoryName;
+      public void unexecute() {
+        wrappeeCommand.unexecute();
 
-                       private Collection features;
+        if ((layer == null) && (currentLayer() != null)) {
+          proxy.getLayerManager().remove(currentLayer());
+        }
 
-                       private boolean visible;
+        if ((layer != null) && (currentLayer() == null)) {
+          proxy.getLayerManager().addLayer(categoryName, layer);
+        }
 
-                       private Layer currentLayer() {
-                               return 
proxy.getLayerManager().getLayer(layerName);
-                       }
+        if (layer != null) {
+          layer.getFeatureCollectionWrapper().clear();
+          layer.getFeatureCollectionWrapper().addAll(features);
+          layer.setVisible(visible);
+        }
+      }
+    };
+  }
 
-                       public void execute() {
-                               layer = currentLayer();
+  /**
+   * Does nothing if the underlying feature collection is not a FeatureDataset.
+   */
+  public static void tryToInvalidateEnvelope(Layer layer) {
+    if (layer.getFeatureCollectionWrapper().getUltimateWrappee() instanceof 
FeatureDataset) {
+      ((FeatureDataset) layer.getFeatureCollectionWrapper()
+          .getUltimateWrappee()).invalidateEnvelope();
+    }
+  }
 
-                               if (layer != null) {
-                                       features = new ArrayList(layer
-                                                       
.getFeatureCollectionWrapper().getFeatures());
-                                       categoryName = layer.getName();
-                                       visible = layer.isVisible();
-                               }
+  public DataSourceQuery getDataSourceQuery() {
+    return dataSourceQuery;
+  }
 
-                               wrappeeCommand.execute();
-                       }
+  public Layer setDataSourceQuery(DataSourceQuery dataSourceQuery) {
+    this.dataSourceQuery = dataSourceQuery;
 
-                       public void unexecute() {
-                               wrappeeCommand.unexecute();
+    return this;
+  }
 
-                               if ((layer == null) && (currentLayer() != 
null)) {
-                                       
proxy.getLayerManager().remove(currentLayer());
-                               }
+  public boolean isFeatureCollectionModified() {
+    return featureCollectionModified;
+  }
 
-                               if ((layer != null) && (currentLayer() == 
null)) {
-                                       
proxy.getLayerManager().addLayer(categoryName, layer);
-                               }
+  public Layer setFeatureCollectionModified(boolean featureCollectionModified) 
{
+    if (this.featureCollectionModified == featureCollectionModified) {
+      return this;
+    }
 
-                               if (layer != null) {
-                                       
layer.getFeatureCollectionWrapper().clear();
-                                       
layer.getFeatureCollectionWrapper().addAll(features);
-                                       layer.setVisible(visible);
-                               }
-                       }
-               };
-       }
+    this.featureCollectionModified = featureCollectionModified;
+    fireLayerChanged(LayerEventType.METADATA_CHANGED);
 
-       /**
-        * Does nothing if the underlying feature collection is not a
-        * FeatureDataset.
-        */
-       public static void tryToInvalidateEnvelope(Layer layer) {
-               if (layer.getFeatureCollectionWrapper().getUltimateWrappee() 
instanceof FeatureDataset) {
-                       ((FeatureDataset) layer.getFeatureCollectionWrapper()
-                                       
.getUltimateWrappee()).invalidateEnvelope();
-               }
-       }
+    return this;
+  }
 
-       public DataSourceQuery getDataSourceQuery() {
-               return dataSourceQuery;
-       }
+  public Collection<String> getFeatureSchemaOperations() {
+    FeatureSchema fs = getFeatureCollectionWrapper().getFeatureSchema();
+    List<String> operations = new ArrayList<String>();
+    for (int i = 0; i < fs.getAttributeCount(); i++) {
+      Operation operation = fs.getOperation(i);
+      if (operation != null)
+        operations.add(fs.getOperation(i).toString());
+      else
+        operations.add("NULL");
+    }
+    return Collections.unmodifiableCollection(operations);
+  }
 
-       public Layer setDataSourceQuery(DataSourceQuery dataSourceQuery) {
-               this.dataSourceQuery = dataSourceQuery;
+  // Used for Operation deserialization
+  Collection<String> expressions;
 
-               return this;
-       }
+  public void addFeatureSchemaOperation(String expression) {
+    if (expressions == null)
+      expressions = new ArrayList<String>();
+    expressions.add(expression);
+  }
 
-       public boolean isFeatureCollectionModified() {
-               return featureCollectionModified;
-       }
+  private void setFeatureSchemaOperations() {
+    FeatureCollection fc = getFeatureCollectionWrapper();
+    if (expressions != null && fc != null
+        && expressions.size() == fc.getFeatureSchema().getAttributeCount()) {
+      FeatureSchema schema = fc.getFeatureSchema();
+      Iterator<String> it = expressions.iterator();
+      for (int i = 0; i < schema.getAttributeCount(); i++) {
+        try {
+          String expression = it.next();
+          if (expression != null && !expression.equals("NULL")
+              && expression.indexOf('\n') > -1) {
+            String[] class_expression = expression.split("\n", 2);
+            Operation op = org.openjump.core.feature.AttributeOperationFactory
+                .getFactory(class_expression[0]).createOperation(
+                    schema.getAttributeType(i), class_expression[1]);
+            schema.setOperation(i, op);
+            schema.setAttributeReadOnly(i, true);
+          }
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+      }
+    }
+    expressions = null;
+  }
 
-       public Layer setFeatureCollectionModified(boolean 
featureCollectionModified) {
-               if (this.featureCollectionModified == 
featureCollectionModified) {
-                       return this;
-               }
-
-               this.featureCollectionModified = featureCollectionModified;
-               fireLayerChanged(LayerEventType.METADATA_CHANGED);
-
-               return this;
-       }
-       
-       public Collection<String> getFeatureSchemaOperations() {
-           FeatureSchema fs = getFeatureCollectionWrapper().getFeatureSchema();
-           List<String> operations = new ArrayList<String>();
-           for (int i = 0 ; i < fs.getAttributeCount()  ; i++) {
-               Operation operation = fs.getOperation(i);
-               if (operation != null) 
operations.add(fs.getOperation(i).toString());
-               else operations.add("NULL");
-           }
-           return Collections.unmodifiableCollection(operations);
-       }
-
-       // Used for Operation deserialization
-       Collection<String> expressions;
-    public void addFeatureSchemaOperation(String expression) {
-           if (expressions == null) expressions = new ArrayList<String>();
-           expressions.add(expression);
-       }
-       
-       private void setFeatureSchemaOperations() {
-           FeatureCollection fc = getFeatureCollectionWrapper();
-           if (expressions != null && fc != null &&
-               expressions.size() == 
fc.getFeatureSchema().getAttributeCount()) {
-               FeatureSchema schema = fc.getFeatureSchema();
-               Iterator<String> it = expressions.iterator();
-               for (int i = 0 ; i < schema.getAttributeCount() ; i++) {
-                   try {
-                       String expression = it.next();
-                       if (expression != null && !expression.equals("NULL") && 
expression.indexOf('\n') > -1) {
-                           String[] class_expression = expression.split("\n", 
2);
-                           Operation op = 
org.openjump.core.feature.AttributeOperationFactory
-                               .getFactory(class_expression[0])
-                               .createOperation(schema.getAttributeType(i), 
class_expression[1]);
-                           schema.setOperation(i, op);
-                           schema.setAttributeReadOnly(i, true);
-                       }
-                   } catch (Exception e) {
-                       e.printStackTrace();
-                   }
-               }
-           }
-           expressions = null;
-       }
-       
 }
\ No newline at end of file

Modified: core/trunk/src/com/vividsolutions/jump/workbench/model/Layerable.java
===================================================================
--- core/trunk/src/com/vividsolutions/jump/workbench/model/Layerable.java       
2015-12-08 18:57:03 UTC (rev 4591)
+++ core/trunk/src/com/vividsolutions/jump/workbench/model/Layerable.java       
2015-12-08 19:00:14 UTC (rev 4592)
@@ -38,39 +38,52 @@
  * A "sheet" of spatial data, overlaid on other "sheets".
  */
 public interface Layerable {
-    public void setName(String name);
+  public void setName(String name);
 
-    public String getName();
+  public String getName();
 
-    public void setVisible(boolean visible);
+  public void setVisible(boolean visible);
 
-    public boolean isVisible();
+  public boolean isVisible();
 
-    public LayerManager getLayerManager();
+  public void setEditable(boolean editable);
 
-    /**
-     * Called by Java2XML
-     */
-    public void setLayerManager(LayerManager layerManager);
+  public boolean isEditable();
 
-       public Blackboard getBlackboard();
+  public boolean isReadonly();
 
-       /**
-        * @return the larger units/pixel value
-        */
-       public Double getMinScale();
-       
-       public Layerable setMinScale(Double minScale);
+  public void setReadonly(boolean value);
 
-       /**
-        * @return the smaller units/pixel value
-        */     
-       public Double getMaxScale();
-       
-       public Layerable setMaxScale(Double maxScale);
-       
-       public boolean isScaleDependentRenderingEnabled();
-       
-       public Layerable setScaleDependentRenderingEnabled(boolean 
scaleDependentRenderingEnabled);
+  public boolean isSelectable();
 
+  public void setSelectable(boolean value);
+
+  public LayerManager getLayerManager();
+
+  /**
+   * Called by Java2XML
+   */
+  public void setLayerManager(LayerManager layerManager);
+
+  public Blackboard getBlackboard();
+
+  /**
+   * @return the larger units/pixel value
+   */
+  public Double getMinScale();
+
+  public Layerable setMinScale(Double minScale);
+
+  /**
+   * @return the smaller units/pixel value
+   */
+  public Double getMaxScale();
+
+  public Layerable setMaxScale(Double maxScale);
+
+  public boolean isScaleDependentRenderingEnabled();
+
+  public Layerable setScaleDependentRenderingEnabled(
+      boolean scaleDependentRenderingEnabled);
+
 }

Modified: core/trunk/src/com/vividsolutions/jump/workbench/ui/AttributeTab.java
===================================================================
--- core/trunk/src/com/vividsolutions/jump/workbench/ui/AttributeTab.java       
2015-12-08 18:57:03 UTC (rev 4591)
+++ core/trunk/src/com/vividsolutions/jump/workbench/ui/AttributeTab.java       
2015-12-08 19:00:14 UTC (rev 4592)
@@ -49,15 +49,14 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.geom.NoninvertibleTransformException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.*;
+import java.util.List;
 
 /**
  * Implements an Attribute Tab.
  */
 
-public class AttributeTab extends JPanel implements LayerNamePanel {
+public class AttributeTab extends JPanel implements LayerNamePanel, 
LayerableNamePanel {
     private BorderLayout borderLayout1 = new BorderLayout();
     private ErrorHandler errorHandler;
     private TaskFrame taskFrame;
@@ -617,6 +616,11 @@
         return selectedLayers;
     }
 
+    public Collection<Layerable> getSelectedLayerables() {
+      List<Layerable> ls = (List)Arrays.asList(getSelectedLayers());
+      return ls;
+    }
+
     public Collection selectedNodes(Class c) {
         if (!Layerable.class.isAssignableFrom(c)) {
             return new ArrayList();

Modified: 
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/EditablePlugIn.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/EditablePlugIn.java  
    2015-12-08 18:57:03 UTC (rev 4591)
+++ 
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/EditablePlugIn.java  
    2015-12-08 19:00:14 UTC (rev 4592)
@@ -32,79 +32,108 @@
 
 package com.vividsolutions.jump.workbench.ui.plugin;
 
-import java.util.Arrays;
-import java.util.Iterator;
-
 import javax.swing.ImageIcon;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
 
 import com.vividsolutions.jump.I18N;
 import com.vividsolutions.jump.workbench.WorkbenchContext;
-import com.vividsolutions.jump.workbench.model.Layer;
+import com.vividsolutions.jump.workbench.model.Layerable;
 import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
 import com.vividsolutions.jump.workbench.plugin.CheckBoxed;
 import com.vividsolutions.jump.workbench.plugin.EnableCheck;
 import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
 import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
 import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import com.vividsolutions.jump.workbench.ui.LayerNamePanel;
+import com.vividsolutions.jump.workbench.ui.LayerNamePanelProxy;
+import com.vividsolutions.jump.workbench.ui.LayerableNamePanel;
 import com.vividsolutions.jump.workbench.ui.cursortool.editing.EditingPlugIn;
 import com.vividsolutions.jump.workbench.ui.images.IconLoader;
 
 public class EditablePlugIn extends AbstractPlugIn implements CheckBoxed {
 
-    private EditingPlugIn editingPlugIn;
+  private EditingPlugIn editingPlugIn;
 
-    public static final ImageIcon ICON = IconLoader.icon("edit.gif");
-    
-    public EditablePlugIn(EditingPlugIn editingPlugIn) {
-      this.editingPlugIn = editingPlugIn;
+  public static final ImageIcon ICON = IconLoader.icon("edit.gif");
+
+  public EditablePlugIn(EditingPlugIn editingPlugIn) {
+    this.editingPlugIn = editingPlugIn;
+  }
+
+  public EditablePlugIn() {
+    super();
+    this.editingPlugIn = EditingPlugIn.getInstance();
+  }
+
+  public boolean execute(PlugInContext context) throws Exception {
+    reportNothingToUndoYet(context);
+
+    Layerable[] layers = getSelectedLayerables(context.getWorkbenchContext());
+    // assume what to do by status of first selected layer
+    boolean makeEditable = !layers[0].isEditable();
+    // set states for each
+    for (Layerable layerable : layers) {
+      layerable.setEditable(makeEditable);
     }
-  
-    public EditablePlugIn() {
-      super();
-      this.editingPlugIn = EditingPlugIn.getInstance();
-    }
 
-    public boolean execute(PlugInContext context) throws Exception {
-        reportNothingToUndoYet(context);
-        boolean makeEditable = !context.getSelectedLayer(0).isEditable();
-        for (Iterator i = 
Arrays.asList(context.getSelectedLayers()).iterator(); i.hasNext(); ) {
-            Layer selectedLayer = (Layer) i.next();
-            selectedLayer.setEditable(makeEditable);
-        }
-        if (makeEditable && 
!editingPlugIn.getToolbox(context.getWorkbenchContext()).isVisible()) {
-            editingPlugIn.execute(context);
-        }
-        return true;
+    // show EditToolBox if we switched to editable
+    if (makeEditable
+        && 
!editingPlugIn.getToolbox(context.getWorkbenchContext()).isVisible()) {
+      editingPlugIn.execute(context);
     }
+    return true;
+  }
 
-    public EnableCheck createEnableCheck(final WorkbenchContext 
workbenchContext) {
-        EnableCheckFactory checkFactory = new 
EnableCheckFactory(workbenchContext);
-        MultiEnableCheck mec = new MultiEnableCheck();
+  public EnableCheck createEnableCheck(final WorkbenchContext 
workbenchContext) {
+    EnableCheckFactory checkFactory = new EnableCheckFactory(workbenchContext);
+    MultiEnableCheck mec = new MultiEnableCheck();
 
-        
mec.add(checkFactory.createWindowWithLayerNamePanelMustBeActiveCheck());
-        mec.add(checkFactory.createAtLeastNLayersMustBeSelectedCheck(1));
+    mec.add(checkFactory.createWindowWithLayerNamePanelMustBeActiveCheck());
+    mec.add(checkFactory.createAtLeastNLayersMustBeSelectedCheck(1));
 
-        mec.add(new EnableCheck() {
-            public String check(JComponent component) {
-                ((JCheckBoxMenuItem) component).setSelected(
-                    
workbenchContext.createPlugInContext().getSelectedLayer(0).isEditable());
-                return null;
-            }
-        });
+    mec.add(new EnableCheck() {
+      public String check(JComponent component) {
+        ((JCheckBoxMenuItem) component)
+            .setSelected(getSelectedLayerables(workbenchContext)[0]
+                .isEditable());
+        return null;
+      }
+    });
 
-        mec.add(new EnableCheck() {
-            public String check(JComponent component) {
-                String errMsg = null;
-                if ( 
workbenchContext.createPlugInContext().getSelectedLayer(0).isReadonly()) {
-                    errMsg = 
I18N.get("ui.plugin.EditablePlugIn.The-selected-layer-cannot-be-made-editable");
-                }
-                return errMsg;
-            }
-        });
+    mec.add(new EnableCheck() {
+      public String check(JComponent component) {
+        String errMsg = null;
+        Layerable[] layers = getSelectedLayerables(workbenchContext);
+        for (int i = 0; i < layers.length; i++) {
+          if (layers[i].isReadonly()) {
+            errMsg = I18N
+                
.get("ui.plugin.EditablePlugIn.The-selected-layer-cannot-be-made-editable");
+            break;
+          }
+        }
+        return errMsg;
+      }
+    });
 
-        return mec;
+    return mec;
+  }
+
+  private static Layerable[] getSelectedLayerables(WorkbenchContext wbc) {
+    Layerable[] layers = new Layerable[] {};
+
+    JInternalFrame frame = wbc.getWorkbench().getFrame()
+        .getActiveInternalFrame();
+    if (frame instanceof LayerNamePanelProxy) {
+      LayerNamePanel lnp = ((LayerNamePanelProxy) frame).getLayerNamePanel();
+      if (lnp instanceof LayerableNamePanel)
+        layers = ((LayerableNamePanel) lnp).getSelectedLayerables().toArray(
+            new Layerable[] {});
+      else
+        layers = lnp.getSelectedLayers();
     }
 
+    return layers;
+  }
 }


------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
_______________________________________________
Jump-pilot-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to