Hi,

Does anybody know how windows users are supposed to patch those kind of 
diff files ?
I only find one java lib claiming to do that (jpatchlib), but 
development is ongoing and it is not yet very user friendly (no gui, no 
jar, no build, only .java) ?

Michaël

>
>Paul
>  
>
>------------------------------------------------------------------------
>
>Index: src/org/openjump/OpenJumpConfiguration.java
>===================================================================
>RCS file: 
>/cvsroot/jump-pilot/openjump/src/org/openjump/OpenJumpConfiguration.java,v
>retrieving revision 1.42
>diff -u -r1.42 OpenJumpConfiguration.java
>--- src/org/openjump/OpenJumpConfiguration.java        24 Mar 2007 12:27:45 
>-0000      1.42
>+++ src/org/openjump/OpenJumpConfiguration.java        11 Jun 2007 19:26:47 
>-0000
>@@ -10,10 +10,16 @@
>  */
> package org.openjump;
> 
>-import javax.swing.JMenu;
>+import java.util.Date;
>+
> import javax.swing.JPopupMenu;
> 
> import org.openjump.core.ccordsys.srid.EnsureAllLayersHaveSRIDStylePlugIn;
>+import org.openjump.core.ui.builder.DateTimeUiBuilder;
>+import org.openjump.core.ui.builder.DateUIBuilder;
>+import org.openjump.core.ui.builder.FeatureUiBuilder;
>+import org.openjump.core.ui.builder.UiBuilderRegistry;
>+import org.openjump.core.ui.component.InfoModelDetailPanel;
> import org.openjump.core.ui.plugin.customize.BeanToolsPlugIn;
> import org.openjump.core.ui.plugin.edit.ReplicateSelectedItemsPlugIn;
> import org.openjump.core.ui.plugin.edit.SelectAllLayerItemsPlugIn;
>@@ -54,19 +60,19 @@
> import org.openjump.core.ui.plugin.view.ShowScalePlugIn;
> import org.openjump.core.ui.plugin.view.ZoomToScalePlugIn;
> import org.openjump.core.ui.plugin.wms.ZoomToWMSPlugIn;
>+import org.openjump.core.ui.style.decoration.ArrowLineStringMiddlepointStyle;
> import org.openjump.sigle.plugin.geoprocessing.layers.SpatialJoinPlugIn;
> import 
> org.openjump.sigle.plugin.geoprocessing.oneLayer.topology.PlanarGraphPlugIn;
> import org.openjump.sigle.plugin.joinTable.JoinTablePlugIn;
> import org.openjump.sigle.plugin.replace.ReplaceValuePlugIn;
> 
>-import org.openjump.core.ui.style.decoration.ArrowLineStringMiddlepointStyle;
>-
>+import com.vividsolutions.jump.feature.Feature;
> import com.vividsolutions.jump.workbench.WorkbenchContext;
> import com.vividsolutions.jump.workbench.plugin.PlugInContext;
>+import com.vividsolutions.jump.workbench.ui.InfoFrame;
> import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
>-import com.vividsolutions.jump.workbench.ui.MenuNames;
>-import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
> import com.vividsolutions.jump.workbench.ui.plugin.BeanShellPlugIn;
>+import com.vividsolutions.jump.workbench.ui.swing.ComponentFactoryRegistry;
> 
> import 
> de.fho.jump.pirol.plugins.EditAttributeByFormula.EditAttributeByFormulaPlugIn;
> import de.latlon.deejump.plugin.SaveLegendPlugIn;
>@@ -360,5 +366,17 @@
>               projectionPlugin.initialize(new PlugInContext(workbenchContext, 
> null, null, null, null));
>               */
> 
>+    /**********************
>+     * UI Builders
>+     **********************/
>+    UiBuilderRegistry htmlrendererRepository = 
>UiBuilderRegistry.getInstance(workbenchContext);
>+    htmlrendererRepository.addRenderer(Feature.class, new FeatureUiBuilder());
>+    htmlrendererRepository.addRenderer(Date.class, new DateTimeUiBuilder());
>+    htmlrendererRepository.addRenderer(java.sql.Date.class, new 
>DateUIBuilder());
>+
>+    /***********************
>+     *  Info Frame Panels
>+     **********************/
>+    ComponentFactoryRegistry.addComponentFactory(workbenchContext, 
>InfoFrame.CLASSIFICATION, InfoModelDetailPanel.class);
>       }
> }
>Index: src/com/vividsolutions/jump/workbench/ui/InfoFrame.java
>===================================================================
>RCS file: 
>/cvsroot/jump-pilot/openjump/src/com/vividsolutions/jump/workbench/ui/InfoFrame.java,v
>retrieving revision 1.3
>diff -u -r1.3 InfoFrame.java
>--- src/com/vividsolutions/jump/workbench/ui/InfoFrame.java    3 Jun 2007 
>20:53:31 -0000       1.3
>+++ src/com/vividsolutions/jump/workbench/ui/InfoFrame.java    11 Jun 2007 
>19:26:46 -0000
>@@ -30,159 +30,201 @@
>  * www.vividsolutions.com
>  */
> package com.vividsolutions.jump.workbench.ui;
>+
> import java.awt.BorderLayout;
>+import java.util.Iterator;
>+import java.util.List;
>+
>+import javax.swing.JComponent;
> import javax.swing.JInternalFrame;
> import javax.swing.JPanel;
> import javax.swing.JTabbedPane;
> import javax.swing.event.InternalFrameAdapter;
> import javax.swing.event.InternalFrameEvent;
>+
> import com.vividsolutions.jts.util.Assert;
> import com.vividsolutions.jump.I18N;
> import com.vividsolutions.jump.workbench.WorkbenchContext;
> import com.vividsolutions.jump.workbench.model.LayerManager;
> import com.vividsolutions.jump.workbench.model.LayerManagerProxy;
> import com.vividsolutions.jump.workbench.model.Task;
>-import com.vividsolutions.jump.workbench.ui.cursortool.editing.EditingPlugIn;
>+import com.vividsolutions.jump.workbench.registry.Registry;
> import com.vividsolutions.jump.workbench.ui.images.IconLoader;
>+import com.vividsolutions.jump.workbench.ui.swing.ComponentFactory;
>+import com.vividsolutions.jump.workbench.ui.swing.ComponentFactoryRegistry;
>+import com.vividsolutions.jump.workbench.ui.swing.IconComponent;
> 
> /**
>  * Provides proxied (non-spatial) views of a Layer.
>  */
>-public class InfoFrame
>-    extends JInternalFrame
>-    implements
>-        LayerManagerProxy,
>-        SelectionManagerProxy,
>-        LayerNamePanelProxy,
>-        TaskFrameProxy,
>-        LayerViewPanelProxy {
>-    public LayerManager getLayerManager() {
>-        return layerManager;
>-    }
>-    public TaskFrame getTaskFrame() {
>-        return attributeTab.getTaskFrame();
>-    }
>-    private LayerManager layerManager;
>-    private BorderLayout borderLayout1 = new BorderLayout();
>-    private AttributeTab attributeTab;
>-    private InfoModel model = new InfoModel();
>-    private GeometryInfoTab geometryInfoTab;
>-    private JTabbedPane tabbedPane = new JTabbedPane();
>-    private WorkbenchFrame workbenchFrame;
>-    public InfoFrame(
>-        WorkbenchContext workbenchContext,
>-        LayerManagerProxy layerManagerProxy,
>-        final TaskFrame taskFrame) {
>-        geometryInfoTab = new GeometryInfoTab(model, workbenchContext);
>-        //Keep my own copy of LayerManager, because it will be nulled in 
>TaskFrame
>-        //when TaskFrame closes (it may in fact already be closed, which is 
>why
>-        //a LayerManagerProxy must be passed in too). But I have to 
>-        //remember to null it when I close. [Jon Aquino]
>-        Assert.isTrue(layerManagerProxy.getLayerManager() != null);
>-        layerManager = layerManagerProxy.getLayerManager();
>-        // I cannot see any reason to add this listener [mmichaud 2007-06-03]
>-        // See also WorkbenchFrame
>-        /*addInternalFrameListener(new InternalFrameAdapter() {
>-            public void internalFrameClosed(InternalFrameEvent e) {
>-                layerManager = new LayerManager();
>-            }
>-        });*/
>-        attributeTab = new AttributeTab(model, workbenchContext, taskFrame, 
>this, false);
>-        addInternalFrameListener(new InternalFrameAdapter() {
>-            public void internalFrameOpened(InternalFrameEvent e) {
>-                attributeTab.getToolBar().updateEnabledState();
>-            }
>-        });
>-        workbenchFrame = workbenchContext.getWorkbench().getFrame();
>-        this.setResizable(true);
>-        this.setClosable(true);
>-        this.setMaximizable(true);
>-        this.setIconifiable(true);
>-        //This size is chosen so that when the user hits the Info tool, the 
>window
>-        //fits between the lower edge of the TaskFrame and the lower edge of 
>the
>-        //WorkbenchFrame. See the call to #setSize in WorkbenchFrame. [Jon 
>Aquino]
>-        //Make sure there's a little space for a custom FeatureTextWriter 
>-        //[Jon Aquino 12/31/2003]
>-        this.setSize(550, 185);
>-        try {
>-            jbInit();
>-        } catch (Exception e) {
>-            e.printStackTrace();
>-        }
>-        tabbedPane.addTab("", IconLoader.icon("Table.gif"), attributeTab, 
>"Table View");
>-        tabbedPane.addTab("", IconLoader.icon("Paper.gif"), geometryInfoTab, 
>"HTML View");
>+public class InfoFrame extends JInternalFrame implements LayerManagerProxy,
>+  SelectionManagerProxy, LayerNamePanelProxy, TaskFrameProxy,
>+  LayerViewPanelProxy {
>+
>+  public static final String CLASSIFICATION = InfoFrame.class.getName();
>+
>+  public LayerManager getLayerManager() {
>+    return layerManager;
>+  }
>+
>+  public TaskFrame getTaskFrame() {
>+    return attributeTab.getTaskFrame();
>+  }
>+
>+  private LayerManager layerManager;
>+
>+  private BorderLayout borderLayout1 = new BorderLayout();
>+
>+  private AttributeTab attributeTab;
>+
>+  private InfoModel model = new InfoModel();
>+
>+  private GeometryInfoTab geometryInfoTab;
>+
>+  private JTabbedPane tabbedPane = new JTabbedPane();
>+
>+  private WorkbenchFrame workbenchFrame;
>+
>+  public InfoFrame(WorkbenchContext workbenchContext,
>+    LayerManagerProxy layerManagerProxy, final TaskFrame taskFrame) {
>+    geometryInfoTab = new GeometryInfoTab(model, workbenchContext);
>+    // Keep my own copy of LayerManager, because it will be nulled in 
>TaskFrame
>+    // when TaskFrame closes (it may in fact already be closed, which is why
>+    // a LayerManagerProxy must be passed in too). But I have to
>+    // remember to null it when I close. [Jon Aquino]
>+    Assert.isTrue(layerManagerProxy.getLayerManager() != null);
>+    layerManager = layerManagerProxy.getLayerManager();
>+    // I cannot see any reason to add this listener [mmichaud 2007-06-03]
>+    // See also WorkbenchFrame
>+    /*
>+     * addInternalFrameListener(new InternalFrameAdapter() { public void
>+     * internalFrameClosed(InternalFrameEvent e) { layerManager = new
>+     * LayerManager(); } });
>+     */
>+    attributeTab = new AttributeTab(model, workbenchContext, taskFrame, this,
>+      false);
>+    addInternalFrameListener(new InternalFrameAdapter() {
>+      public void internalFrameOpened(InternalFrameEvent e) {
>+        attributeTab.getToolBar().updateEnabledState();
>+      }
>+    });
>+    workbenchFrame = workbenchContext.getWorkbench().getFrame();
>+    this.setResizable(true);
>+    this.setClosable(true);
>+    this.setMaximizable(true);
>+    this.setIconifiable(true);
>+    // This size is chosen so that when the user hits the Info tool, the 
>window
>+    // fits between the lower edge of the TaskFrame and the lower edge of the
>+    // WorkbenchFrame. See the call to #setSize in WorkbenchFrame. [Jon 
>Aquino]
>+    // Make sure there's a little space for a custom FeatureTextWriter
>+    // [Jon Aquino 12/31/2003]
>+    this.setSize(550, 185);
>+    try {
>+      jbInit();
>+    } catch (Exception e) {
>+      e.printStackTrace();
>+    }
>+    tabbedPane.addTab("", IconLoader.icon("Table.gif"), attributeTab,
>+      "Table View");
>+    tabbedPane.addTab("", IconLoader.icon("Paper.gif"), geometryInfoTab,
>+      "HTML View");
>+
>+    for (Iterator factories = 
>ComponentFactoryRegistry.getComponentFactories(workbenchContext, 
>CLASSIFICATION).iterator(); factories.hasNext();) {
>+      ComponentFactory factory = (ComponentFactory)factories.next();
>+      JComponent component = factory.createComponent();
>+      if (component instanceof IconComponent) {
>+        IconComponent iconComponent = (IconComponent)component;
>+        tabbedPane.addTab(component.getName(), iconComponent.getIcon(), 
>component,
>+          component.getToolTipText());
>+      } else {
>+        tabbedPane.addTab(component.getName(), null, component,
>+          component.getToolTipText());
>+      }
>+      if (component instanceof InfoModelAware) {
>+        InfoModelAware tabAware = (InfoModelAware)component;
>+        tabAware.setInfoModel(model);
>+      }
>+    }
>+    updateTitle(taskFrame.getTask().getName());
>+    taskFrame.getTask().add(new Task.NameListener() {
>+      public void taskNameChanged(String name) {
>         updateTitle(taskFrame.getTask().getName());
>-        taskFrame.getTask().add(new Task.NameListener() {
>-            public void taskNameChanged(String name) {
>-                updateTitle(taskFrame.getTask().getName());
>-            }
>-        });
>-        addInternalFrameListener(new InternalFrameAdapter() {
>-            public void internalFrameClosed(InternalFrameEvent e) {
>-                //Assume that there are no other views on the model
>-                model.dispose();
>-            }
>-        });
>-    }
>-    public JPanel getAttributeTab() {
>-        return attributeTab;
>-    }
>-    public JPanel getGeometryTab() {
>-        return geometryInfoTab;
>-    }
>-    public void setSelectedTab(JPanel tab) {
>-        tabbedPane.setSelectedComponent(tab);
>-    }
>-    public static String title(String taskName) {
>-        return I18N.get("ui.InfoFrame.feature-info")+": " + taskName;
>-    }
>-    private void updateTitle(String taskName) {
>-        setTitle(title(taskName));
>-    }
>-    public InfoModel getModel() {
>-        return model;
>-    }
>-    private void jbInit() throws Exception {
>-        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
>-        // With the DefaultInternalFrameCloser of WorkbenchFrame,
>-        // I think this code is no more necessary [mmichaud 2007-06-03]
>-        /*addInternalFrameListener(new InternalFrameAdapter() {
>-            public void internalFrameClosing(InternalFrameEvent e) {
>-                //Regardless of the defaultCloseOperation, this InfoFrame 
>should be
>-                //removed from the WorkbenchFrame when the user hits X so it 
>won't
>-                //appear on the Window list. [Jon Aquino]
>-                try {
>-                    workbenchFrame.removeInternalFrame(InfoFrame.this);
>-                } catch (Exception x) {
>-                    workbenchFrame.handleThrowable(x);
>-                }
>-            }
>-        });*/
>-        this.setTitle(I18N.get("ui.InfoFrame.feature-info"));
>-        this.getContentPane().setLayout(borderLayout1);
>-        tabbedPane.setTabPlacement(JTabbedPane.LEFT);
>-        this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
>-    }
>-    public void surface() {
>-        JInternalFrame activeFrame = workbenchFrame.getActiveInternalFrame();
>-        if (!workbenchFrame.hasInternalFrame(this)) {
>-            workbenchFrame.addInternalFrame(this, false, true);
>-        }
>-        if (activeFrame != null) {
>-            workbenchFrame.activateFrame(activeFrame);
>-        }
>-        moveToFront();
>-        //Move this frame to the front, but don't activate it if the 
>TaskFrame is
>-        //active. Otherwise the user would need to re-activate the TaskFrame 
>before
>-        //making another Info gesture. [Jon Aquino]
>-    }
>-    public SelectionManager getSelectionManager() {
>-        return attributeTab.getPanel().getSelectionManager();
>-    }
>-    public LayerNamePanel getLayerNamePanel() {
>-        return attributeTab;
>-    }
>-    public LayerViewPanel getLayerViewPanel() {
>-        return getTaskFrame().getLayerViewPanel();
>-    }
>+      }
>+    });
>+    addInternalFrameListener(new InternalFrameAdapter() {
>+      public void internalFrameClosed(InternalFrameEvent e) {
>+        // Assume that there are no other views on the model
>+        model.dispose();
>+      }
>+    });
>+  }
>+
>+  public JPanel getAttributeTab() {
>+    return attributeTab;
>+  }
>+
>+  public JPanel getGeometryTab() {
>+    return geometryInfoTab;
>+  }
>+
>+  public void setSelectedTab(JPanel tab) {
>+    tabbedPane.setSelectedComponent(tab);
>+  }
>+
>+  public static String title(String taskName) {
>+    return I18N.get("ui.InfoFrame.feature-info") + ": " + taskName;
>+  }
>+
>+  private void updateTitle(String taskName) {
>+    setTitle(title(taskName));
>+  }
>+
>+  public InfoModel getModel() {
>+    return model;
>+  }
>+
>+  private void jbInit() throws Exception {
>+    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
>+    // With the DefaultInternalFrameCloser of WorkbenchFrame,
>+    // I think this code is no more necessary [mmichaud 2007-06-03]
>+    /*
>+     * addInternalFrameListener(new InternalFrameAdapter() { public void
>+     * internalFrameClosing(InternalFrameEvent e) { //Regardless of the
>+     * defaultCloseOperation, this InfoFrame should be //removed from the
>+     * WorkbenchFrame when the user hits X so it won't //appear on the Window
>+     * list. [Jon Aquino] try {
>+     * workbenchFrame.removeInternalFrame(InfoFrame.this); } catch (Exception 
>x) {
>+     * workbenchFrame.handleThrowable(x); } } });
>+     */
>+    this.setTitle(I18N.get("ui.InfoFrame.feature-info"));
>+    this.getContentPane().setLayout(borderLayout1);
>+    tabbedPane.setTabPlacement(JTabbedPane.LEFT);
>+    this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
>+  }
>+
>+  public void surface() {
>+    JInternalFrame activeFrame = workbenchFrame.getActiveInternalFrame();
>+    if (!workbenchFrame.hasInternalFrame(this)) {
>+      workbenchFrame.addInternalFrame(this, false, true);
>+    }
>+    if (activeFrame != null) {
>+      workbenchFrame.activateFrame(activeFrame);
>+    }
>+    moveToFront();
>+    // Move this frame to the front, but don't activate it if the TaskFrame is
>+    // active. Otherwise the user would need to re-activate the TaskFrame 
>before
>+    // making another Info gesture. [Jon Aquino]
>+  }
>+
>+  public SelectionManager getSelectionManager() {
>+    return attributeTab.getPanel().getSelectionManager();
>+  }
>+
>+  public LayerNamePanel getLayerNamePanel() {
>+    return attributeTab;
>+  }
>+
>+  public LayerViewPanel getLayerViewPanel() {
>+    return getTaskFrame().getLayerViewPanel();
>+  }
> }
>Index: src/com/vividsolutions/jump/workbench/ui/InfoModel.java
>===================================================================
>RCS file: 
>/cvsroot/jump-pilot/openjump/src/com/vividsolutions/jump/workbench/ui/InfoModel.java,v
>retrieving revision 1.1
>diff -u -r1.1 InfoModel.java
>--- src/com/vividsolutions/jump/workbench/ui/InfoModel.java    16 Jun 2005 
>22:11:46 -0000      1.1
>+++ src/com/vividsolutions/jump/workbench/ui/InfoModel.java    11 Jun 2007 
>19:26:46 -0000
>@@ -92,13 +92,13 @@
> 
>     public void remove(Layer layer) {
>         LayerTableModel layerTableModel = getTableModel(layer);
>-        ((LayerTableModel) layerToTableModelMap.get(layer)).dispose();
>-        layerToTableModelMap.remove(layer);
> 
>         for (Iterator i = listeners.iterator(); i.hasNext();) {
>             InfoModelListener listener = (InfoModelListener) i.next();
>             listener.layerRemoved(layerTableModel);
>         }
>+        ((LayerTableModel) layerToTableModelMap.get(layer)).dispose();
>+        layerToTableModelMap.remove(layer);
>     }
> 
>     public void clear() {
>Index: src/com/vividsolutions/jump/feature/FeatureSchema.java
>===================================================================
>RCS file: 
>/cvsroot/jump-pilot/openjump/src/com/vividsolutions/jump/feature/FeatureSchema.java,v
>retrieving revision 1.2
>diff -u -r1.2 FeatureSchema.java
>--- src/com/vividsolutions/jump/feature/FeatureSchema.java     27 Jul 2005 
>21:20:09 -0000      1.2
>+++ src/com/vividsolutions/jump/feature/FeatureSchema.java     11 Jun 2007 
>19:26:45 -0000
>@@ -51,6 +51,9 @@
>     private int attributeCount = 0;
>     private ArrayList attributeNames = new ArrayList();
>     private ArrayList attributeTypes = new ArrayList();
>+    
>+    /** The name of the schema. */
>+    private String name;
> 
>     //todo Deep-copy! [Jon Aquino]
>     //deep copy done 25. Juli 2005 [sstein] 
>@@ -195,4 +198,22 @@
>               return coordinateSystem;
>       }
> 
>+    /**
>+     * Get the name of the schema.
>+     * 
>+     * @return The name of the schema.
>+     */
>+    public String getName() {
>+      return name;
>+    }
>+
>+    /**
>+     * Set the name of the schema.
>+     * 
>+     * @param name The name of the schema.
>+     */
>+    public void setName(String name) {
>+      this.name = name;
>+    }
>+
> }
>Index: src/com/vividsolutions/jump/workbench/ui/InfoModelAware.java
>===================================================================
>RCS file: src/com/vividsolutions/jump/workbench/ui/InfoModelAware.java
>diff -N src/com/vividsolutions/jump/workbench/ui/InfoModelAware.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/com/vividsolutions/jump/workbench/ui/InfoModelAware.java       1 Jan 
>1970 00:00:00 -0000
>@@ -0,0 +1,6 @@
>+package com.vividsolutions.jump.workbench.ui;
>+
>+public interface InfoModelAware {
>+  InfoModel getInfoModel();
>+  void setInfoModel(InfoModel model);
>+}
>Index: src/org/openjump/core/ui/builder/StringUiBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/StringUiBuilder.java
>diff -N src/org/openjump/core/ui/builder/StringUiBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/StringUiBuilder.java      1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,12 @@
>+package org.openjump.core.ui.builder;
>+
>+import com.vividsolutions.jump.workbench.ui.GUIUtil;
>+
>+public class StringUiBuilder extends AbstractUiBuilder {
>+
>+  public void appendHtml(StringBuffer s, Object object) {
>+    if (object != null) {
>+      s.append(GUIUtil.escapeHTML(object.toString(), false, false));
>+    }
>+  }
>+}
>Index: src/org/openjump/core/ui/component/FeatureViewPanel.java
>===================================================================
>RCS file: src/org/openjump/core/ui/component/FeatureViewPanel.java
>diff -N src/org/openjump/core/ui/component/FeatureViewPanel.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/component/FeatureViewPanel.java   1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,100 @@
>+package org.openjump.core.ui.component;
>+
>+import java.awt.BorderLayout;
>+import java.awt.Color;
>+
>+import javax.swing.JEditorPane;
>+import javax.swing.JPanel;
>+import javax.swing.JScrollPane;
>+
>+import org.openjump.core.ui.builder.FeatureUiBuilder;
>+import org.openjump.core.ui.builder.UiBuilderRegistry;
>+
>+import com.vividsolutions.jump.feature.Feature;
>+import com.vividsolutions.jump.workbench.WorkbenchContext;
>+import com.vividsolutions.jump.workbench.model.Layer;
>+import com.vividsolutions.jump.workbench.ui.GUIUtil;
>+
>+public class FeatureViewPanel extends JPanel {
>+  private JEditorPane editorPane = new JEditorPane();
>+
>+  private Feature feature;
>+
>+  private FeatureUiBuilder renderer;
>+
>+  private Layer layer;
>+
>+  public FeatureViewPanel(WorkbenchContext context) {
>+    renderer = new FeatureUiBuilder();
>+    renderer.setRegistry(UiBuilderRegistry.getInstance(context));
>+    jbInit();
>+  }
>+
>+  void jbInit() {
>+    JScrollPane scrollPane = new JScrollPane();
>+    editorPane.setEditable(false);
>+    editorPane.setText("jEditorPane1");
>+    editorPane.setContentType("text/html");
>+    this.setLayout(new BorderLayout());
>+    this.add(scrollPane, BorderLayout.CENTER);
>+    scrollPane.getViewport().add(editorPane, null);
>+  }
>+
>+  public Color sidebarColor(Layer layer) {
>+    Color basicColor = layer.getBasicStyle().isRenderingFill() ? 
>layer.getBasicStyle()
>+      .getFillColor()
>+      : layer.getBasicStyle().getLineColor();
>+    int alpha = layer.getBasicStyle().getAlpha();
>+    return GUIUtil.toSimulatedTransparency(GUIUtil.alphaColor(basicColor, 
>alpha));
>+  }
>+
>+  private String toHTML(Color color) {
>+    String colorString = "#";
>+    colorString += pad(Integer.toHexString(color.getRed()));
>+    colorString += pad(Integer.toHexString(color.getGreen()));
>+    colorString += pad(Integer.toHexString(color.getBlue()));
>+    return colorString;
>+  }
>+
>+  private String pad(String s) {
>+    return (s.length() == 1) ? ("0" + s) : s;
>+  }
>+
>+  public void updateText() {
>+    if (feature != null) {
>+      StringBuffer s = new StringBuffer();
>+      s.append("<div style=\"padding-left: 5px; background-color: "
>+        + toHTML(sidebarColor(layer)) + "\">");
>+      s.append("<div style=\"font-size: 14pt;font-weight:bold;padding: 1px 
>2px;margin-bottom: 3px; background-color:white\">");
>+      s.append(layer.getName());
>+      s.append("</div>");
>+      renderer.appendHtml(s, feature, false);
>+      editorPane.setText(s.toString());
>+      s.append("</div>");
>+    } else {
>+      editorPane.setText("");
>+    }
>+    editorPane.setCaretPosition(0);
>+  }
>+
>+  /**
>+   * @return the feature
>+   */
>+  public Feature getFeature() {
>+    return feature;
>+  }
>+
>+  /**
>+   * @param feature the feature to set
>+   */
>+  public void setFeature(Feature feature) {
>+    this.feature = feature;
>+    updateText();
>+  }
>+
>+  public void setLayer(Layer layer) {
>+    this.layer = layer;
>+
>+  }
>+
>+}
>Index: 
>src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactoryRegistry.java
>===================================================================
>RCS file: 
>src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactoryRegistry.java
>diff -N 
>src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactoryRegistry.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ 
>src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactoryRegistry.java   
>    1 Jan 1970 00:00:00 -0000
>@@ -0,0 +1,60 @@
>+package com.vividsolutions.jump.workbench.ui.swing;
>+
>+import java.util.List;
>+
>+import com.vividsolutions.jump.workbench.WorkbenchContext;
>+import com.vividsolutions.jump.workbench.registry.Registry;
>+
>+/**
>+ * Utility class to manage the list of [EMAIL PROTECTED] ComponentFactory} in 
>the
>+ * [EMAIL PROTECTED] Registry} for the classification.
>+ * 
>+ * @author Paul Austin
>+ * @see ComponentFactory
>+ */
>+public class ComponentFactoryRegistry {
>+  /**
>+   * Add a new component factory for the component class to the registry for 
>the
>+   * classification.
>+   * 
>+   * @param context The workbench context that contains the registry.
>+   * @param classification The classification to add the factory to.
>+   * @param componentClass The component class.
>+   * @see WorkbenchContextComponentFactory
>+   */
>+  public static void addComponentFactory(WorkbenchContext context,
>+    String classification, Class componentClass) {
>+    WorkbenchContextComponentFactory factory = new 
>WorkbenchContextComponentFactory(
>+      componentClass, context);
>+    addComponentFactory(context, classification, factory);
>+  }
>+
>+  /**
>+   * Add the component factory to the registry for the classification.
>+   * 
>+   * @param context The workbench context that contains the registry.
>+   * @param classification The classification to add the factory to.
>+   * @param factory The factory that creates the components.
>+   */
>+  public static void addComponentFactory(WorkbenchContext context,
>+    String classification, ComponentFactory factory) {
>+    Registry registry = context.getRegistry();
>+    registry.createEntry(classification, factory);
>+  }
>+
>+  /**
>+   * Get the component factories for the classification from the registry.
>+   * 
>+   * @param context The workbench context that contains the registry.
>+   * @param classification The classification to add the factory to.
>+   * @return The list of component factories
>+   * @see ComponentFactory
>+   */
>+  public static List getComponentFactories(WorkbenchContext context,
>+    String classification) {
>+    Registry registry = context.getRegistry();
>+    List factories = registry.getEntries(classification);
>+    return factories;
>+  }
>+
>+}
>Index: src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactory.java
>===================================================================
>RCS file: src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactory.java
>diff -N src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactory.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/com/vividsolutions/jump/workbench/ui/swing/ComponentFactory.java       
>1 Jan 1970 00:00:00 -0000
>@@ -0,0 +1,7 @@
>+package com.vividsolutions.jump.workbench.ui.swing;
>+
>+import javax.swing.JComponent;
>+
>+public interface ComponentFactory {
>+  JComponent createComponent();
>+}
>Index: src/org/openjump/core/ui/builder/AbstractUiBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/AbstractUiBuilder.java
>diff -N src/org/openjump/core/ui/builder/AbstractUiBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/AbstractUiBuilder.java    1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,28 @@
>+package org.openjump.core.ui.builder;
>+
>+
>+public abstract class AbstractUiBuilder implements UiBuilder {
>+  private UiBuilderRegistry registry;
>+
>+  public String toHtml(final Object object) {
>+    StringBuffer s = new StringBuffer();
>+    appendHtml(s, object);
>+    return s.toString();
>+  }
>+
>+  /**
>+   * @return the registry
>+   */
>+  public UiBuilderRegistry getRegistry() {
>+    return registry;
>+  }
>+
>+  /**
>+   * @param registry the registry to set
>+   */
>+  public void setRegistry(UiBuilderRegistry registry) {
>+    this.registry = registry;
>+  }
>+  
>+  
>+}
>Index: src/org/openjump/core/ui/component/InfoModelDetailPanel.java
>===================================================================
>RCS file: src/org/openjump/core/ui/component/InfoModelDetailPanel.java
>diff -N src/org/openjump/core/ui/component/InfoModelDetailPanel.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/component/InfoModelDetailPanel.java       1 Jan 
>1970 00:00:00 -0000
>@@ -0,0 +1,244 @@
>+package org.openjump.core.ui.component;
>+
>+import java.awt.BorderLayout;
>+import java.awt.event.ActionEvent;
>+import java.awt.event.ActionListener;
>+import java.util.Iterator;
>+
>+import javax.swing.Icon;
>+import javax.swing.JButton;
>+import javax.swing.JPanel;
>+import javax.swing.JTextField;
>+import javax.swing.JTextPane;
>+
>+import org.openjump.core.ui.plugin.enablecheck.BooleanPropertyEnableCheck;
>+
>+import com.vividsolutions.jump.I18N;
>+import com.vividsolutions.jump.feature.Feature;
>+import com.vividsolutions.jump.workbench.WorkbenchContext;
>+import com.vividsolutions.jump.workbench.model.Layer;
>+import com.vividsolutions.jump.workbench.ui.EnableableToolBar;
>+import com.vividsolutions.jump.workbench.ui.InfoModel;
>+import com.vividsolutions.jump.workbench.ui.InfoModelAware;
>+import com.vividsolutions.jump.workbench.ui.InfoModelListener;
>+import com.vividsolutions.jump.workbench.ui.LayerTableModel;
>+import com.vividsolutions.jump.workbench.ui.images.IconLoader;
>+import com.vividsolutions.jump.workbench.ui.swing.IconComponent;
>+
>+public class InfoModelDetailPanel extends JPanel implements InfoModelAware,
>+  InfoModelListener, IconComponent {
>+  private Icon icon = IconLoader.icon("Attribute.gif");
>+
>+  private InfoModel infoModel;
>+
>+  private FeatureViewPanel featureDetailPanel;
>+
>+  private EnableableToolBar toolBar = new EnableableToolBar();
>+
>+  private int layerFeatureIndex = 0;
>+
>+  private int featureIndex = 0;
>+
>+  private int featureCount = 0;
>+
>+  private Feature currentFeature;
>+
>+  private JTextField featureIndexField;
>+
>+  private JTextPane featureCountPane;
>+
>+  public InfoModelDetailPanel(WorkbenchContext context) {
>+    setToolTipText("Detail View");
>+    featureDetailPanel = new FeatureViewPanel(context);
>+
>+    try {
>+      jbInit();
>+    } catch (Exception ex) {
>+      ex.printStackTrace();
>+    }
>+    toolBar.add(new JButton(), I18N.get("ui.GeometryInfoTab.attributes"),
>+      IconLoader.icon("Start.gif"), new ActionListener() {
>+        public void actionPerformed(ActionEvent e) {
>+          firstFeature();
>+        }
>+      }, new BooleanPropertyEnableCheck(this, "isAtFirst", false));
>+    toolBar.add(new JButton(), I18N.get("ui.GeometryInfoTab.attributes"),
>+      IconLoader.icon("Prev.gif"), new ActionListener() {
>+        public void actionPerformed(ActionEvent e) {
>+          previousFeature();
>+        }
>+      }, new BooleanPropertyEnableCheck(this, "isAtFirst", false));
>+    toolBar.add(new JButton(), I18N.get("ui.GeometryInfoTab.attributes"),
>+      IconLoader.icon("Next.gif"), new ActionListener() {
>+        public void actionPerformed(ActionEvent e) {
>+          nextFeature();
>+        }
>+      }, new BooleanPropertyEnableCheck(this, "isAtLast", false));
>+    toolBar.add(new JButton(), I18N.get("ui.GeometryInfoTab.attributes"),
>+      IconLoader.icon("End.gif"), new ActionListener() {
>+        public void actionPerformed(ActionEvent e) {
>+          lastFeature();
>+        }
>+      }, new BooleanPropertyEnableCheck(this, "isAtLast", false));
>+    featureIndexField = new JTextField();
>+    toolBar.add(featureIndexField);
>+    featureCountPane = new JTextPane();
>+    toolBar.add(featureCountPane);
>+
>+  }
>+
>+  public boolean isAtFirst() {
>+    return featureIndex == 0;
>+  }
>+
>+  public boolean isAtLast() {
>+    return featureIndex >= featureCount - 1;
>+  }
>+
>+  protected void firstFeature() {
>+    setSelectedFeature(0);
>+  }
>+
>+  protected void previousFeature() {
>+    setSelectedFeature(featureIndex - 1);
>+  }
>+
>+  protected void nextFeature() {
>+    setSelectedFeature(featureIndex + 1);
>+  }
>+
>+  protected void lastFeature() {
>+    setSelectedFeature(featureCount - 1);
>+  }
>+
>+  private void updateText() {
>+    featureDetailPanel.updateText();
>+  }
>+
>+  void jbInit() throws Exception {
>+    setLayout(new BorderLayout());
>+    add(featureDetailPanel, BorderLayout.CENTER);
>+    add(toolBar, BorderLayout.NORTH);
>+  }
>+
>+  public InfoModel getInfoModel() {
>+    return infoModel;
>+  }
>+
>+  public void setInfoModel(InfoModel model) {
>+    this.infoModel = model;
>+    model.addListener(this);
>+    for (Iterator layers = infoModel.getLayers().iterator(); 
>layers.hasNext();) {
>+      Layer layer = (Layer)layers.next();
>+      LayerTableModel layerModel = infoModel.getTableModel(layer);
>+      layerAdded(layerModel);
>+    }
>+    firstFeature();
>+  }
>+
>+  public void layerAdded(LayerTableModel layerTableModel) {
>+    int rowCount = layerTableModel.getRowCount();
>+    featureCount += rowCount;
>+    if (featureCount == rowCount) {
>+      setSelectedFeature(0);
>+    } else {
>+      update();
>+    }
>+  }
>+
>+  public void layerRemoved(LayerTableModel layerTableModel) {
>+    int rowCount = layerTableModel.getRowCount();
>+    int layerIndex = 0;
>+    boolean finish = false;
>+    featureCount -= rowCount;
>+    Iterator layers = infoModel.getLayers().iterator();
>+    while (layers.hasNext() && !finish) {
>+      Layer layer = (Layer)layers.next();
>+      LayerTableModel layerModel = infoModel.getTableModel(layer);
>+      if (featureIndex < layerIndex) {
>+        finish = true;
>+      } else if (layerModel == layerTableModel) {
>+        featureIndex -= rowCount - 1;
>+        if (featureIndex < layerIndex) {
>+          featureIndex = layerIndex;
>+        }
>+        if (featureIndex >= featureCount) {
>+          featureIndex = 0;
>+        }
>+        layerFeatureIndex = 0;
>+        finish = true;
>+      } else {
>+        layerIndex += layerModel.getRowCount();
>+      }
>+    }
>+    setSelectedFeature(featureIndex);
>+  }
>+
>+  private void setSelectedFeature(final int i) {
>+    boolean found = false;
>+    if (featureCount != 0) {
>+      if (i >= featureCount) {
>+        if (featureCount == 0) {
>+          featureIndex = 0;
>+        } else {
>+          featureIndex = featureCount - 1;
>+        }
>+      } else if (i <= 0) {
>+        featureIndex = 0;
>+      } else {
>+        featureIndex = i;
>+      }
>+      int layerIndex = 0;
>+      Iterator layers = infoModel.getLayers().iterator();
>+      while (layers.hasNext() && !found) {
>+        Layer layer = (Layer)layers.next();
>+        LayerTableModel layerModel = infoModel.getTableModel(layer);
>+
>+        int layerRows = layerModel.getRowCount();
>+        if (featureIndex < layerIndex + layerRows) {
>+          layerFeatureIndex = featureIndex - layerIndex;
>+          currentFeature = layerModel.getFeature(layerFeatureIndex);
>+          featureDetailPanel.setLayer(layer);
>+          featureDetailPanel.setFeature(currentFeature);
>+          update();
>+          found = true;
>+        } else {
>+          layerIndex += layerRows;
>+        }
>+      }
>+    }
>+    if (!found) {
>+      currentFeature = null;
>+      featureDetailPanel.setFeature(null);
>+      update();
>+    }
>+  }
>+
>+  private void update() {
>+    if (currentFeature != null) {
>+      featureDetailPanel.setFeature(currentFeature);
>+      featureIndexField.setText(String.valueOf(featureIndex + 1));
>+      featureCountPane.setText(" of " + featureCount);
>+    } else {
>+      featureDetailPanel.setFeature(null);
>+      featureIndexField.setText("0");
>+      featureCountPane.setText(" of 0");
>+    }
>+    toolBar.updateEnabledState();
>+  }
>+
>+  /**
>+   * @return the icon
>+   */
>+  public Icon getIcon() {
>+    return icon;
>+  }
>+
>+  /**
>+   * @param icon the icon to set
>+   */
>+  public void setIcon(Icon icon) {
>+    this.icon = icon;
>+  }
>+
>+}
>Index: 
>src/com/vividsolutions/jump/workbench/ui/swing/WorkbenchContextComponentFactory.java
>===================================================================
>RCS file: 
>src/com/vividsolutions/jump/workbench/ui/swing/WorkbenchContextComponentFactory.java
>diff -N 
>src/com/vividsolutions/jump/workbench/ui/swing/WorkbenchContextComponentFactory.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ 
>src/com/vividsolutions/jump/workbench/ui/swing/WorkbenchContextComponentFactory.java
>       1 Jan 1970 00:00:00 -0000
>@@ -0,0 +1,44 @@
>+package com.vividsolutions.jump.workbench.ui.swing;
>+
>+import java.lang.reflect.Constructor;
>+
>+import javax.swing.JComponent;
>+
>+import com.vividsolutions.jump.workbench.WorkbenchContext;
>+
>+public class WorkbenchContextComponentFactory implements ComponentFactory {
>+  private Class componentClass;
>+
>+  private WorkbenchContext context;
>+
>+  private Constructor constructor;
>+
>+  public WorkbenchContextComponentFactory(Class componentClass,
>+    WorkbenchContext context) {
>+    this.componentClass = componentClass;
>+    this.context = context;
>+    try {
>+      constructor = componentClass.getConstructor(new Class[] {
>+        WorkbenchContext.class
>+      });
>+    } catch (Throwable e) {
>+      throw new RuntimeException(componentClass
>+        + " must have a constructor with argument " + WorkbenchContext.class, 
>e);
>+    }
>+  }
>+
>+  public JComponent createComponent() {
>+    try {
>+      return (JComponent)constructor.newInstance(new Object[] {
>+        context
>+      });
>+    } catch (RuntimeException e) {
>+      throw e;
>+    } catch (Error e) {
>+      throw e;
>+    } catch (Exception e) {
>+      throw new RuntimeException("Unable to construct " + componentClass, e);
>+    }
>+  }
>+
>+}
>Index: src/org/openjump/core/ui/builder/UiBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/UiBuilder.java
>diff -N src/org/openjump/core/ui/builder/UiBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/UiBuilder.java    1 Jan 1970 00:00:00 
>-0000
>@@ -0,0 +1,10 @@
>+package org.openjump.core.ui.builder;
>+
>+public interface UiBuilder {
>+   void appendHtml(StringBuffer s, Object object);
>+   String toHtml(Object object);
>+  
>+   UiBuilderRegistry getRegistry();
>+   void setRegistry(UiBuilderRegistry registry);
>+  
>+}
>Index: src/org/openjump/core/ui/builder/UiBuilderRegistry.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/UiBuilderRegistry.java
>diff -N src/org/openjump/core/ui/builder/UiBuilderRegistry.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/UiBuilderRegistry.java    1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,71 @@
>+package org.openjump.core.ui.builder;
>+
>+import java.util.HashMap;
>+import java.util.LinkedHashMap;
>+import java.util.Map;
>+
>+import com.vividsolutions.jump.util.Blackboard;
>+import com.vividsolutions.jump.workbench.WorkbenchContext;
>+
>+public class UiBuilderRegistry {
>+  private static final String BLACKBOARD_KEY = 
>UiBuilderRegistry.class.getName();
>+
>+  private static final StringUiBuilder DEFAULT_RENDERER = new 
>StringUiBuilder();
>+
>+  private Map renderers = new LinkedHashMap();
>+
>+  public static UiBuilderRegistry getInstance(WorkbenchContext context) {
>+    Blackboard blackboard = context.getBlackboard();
>+    UiBuilderRegistry repository = 
>(UiBuilderRegistry)blackboard.get(BLACKBOARD_KEY);
>+    if (repository == null) {
>+      repository = new UiBuilderRegistry();
>+      blackboard.put(BLACKBOARD_KEY, repository);
>+    }
>+    return repository;
>+  }
>+
>+  public void addRenderer(Class clazz, UiBuilder builder) {
>+    renderers.put(clazz, builder);
>+    builder.setRegistry(this);
>+  }
>+
>+  public UiBuilder getRenderer(Class clazz) {
>+    UiBuilder renderer = getRendererPrivate(clazz);
>+    if (renderer != null) {
>+      return renderer;
>+    } else {
>+      return DEFAULT_RENDERER;
>+    }
>+  }
>+
>+  private UiBuilder getRendererPrivate(Class clazz) {
>+    if (clazz != null) {
>+      UiBuilder renderer = (UiBuilder)renderers.get(clazz);
>+      if (renderer == null) {
>+        Class superClass = clazz.getSuperclass();
>+        if (superClass != Object.class) {
>+          renderer = getRendererPrivate(superClass);
>+        }
>+        Class[] interfaces = clazz.getInterfaces();
>+        for (int i = 0; i < interfaces.length && renderer == null; i++) {
>+          Class interfaceClass = interfaces[i];
>+          renderer = getRendererPrivate(interfaceClass);
>+        }
>+      }
>+      return renderer;
>+    } else {
>+      return null;
>+    }
>+  }
>+
>+  public String toHtml(Object object) {
>+    if (object != null) {
>+      Class objectClass = object.getClass();
>+      UiBuilder renderer = getRenderer(objectClass);
>+      String html = renderer.toHtml(object);
>+      return html;
>+    } else {
>+      return null;
>+    }
>+  }
>+}
>Index: 
>src/org/openjump/core/ui/plugin/enablecheck/BooleanPropertyEnableCheck.java
>===================================================================
>RCS file: 
>src/org/openjump/core/ui/plugin/enablecheck/BooleanPropertyEnableCheck.java
>diff -N 
>src/org/openjump/core/ui/plugin/enablecheck/BooleanPropertyEnableCheck.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ 
>src/org/openjump/core/ui/plugin/enablecheck/BooleanPropertyEnableCheck.java    
>    1 Jan 1970 00:00:00 -0000
>@@ -0,0 +1,61 @@
>+package org.openjump.core.ui.plugin.enablecheck;
>+
>+import java.lang.reflect.Method;
>+
>+import javax.swing.JComponent;
>+
>+import com.vividsolutions.jump.workbench.plugin.EnableCheck;
>+
>+public class BooleanPropertyEnableCheck implements EnableCheck {
>+  String disabledMessage = "";
>+
>+  /** The check method. */
>+  private Method method;
>+
>+  /** The object to invoke the method on.*/
>+  private Object object;
>+
>+  /** The expected value to be returned for the check to be enabled. */
>+  private boolean expectedValue;
>+  
>+  /**
>+   * 
>+   * @param object The object to invoke the method on.
>+   * @param checkMethodName The name of the check method which returns a 
>boolean value.
>+   */
>+  public BooleanPropertyEnableCheck(final Object object, final String 
>checkMethodName) {
>+    this(object, checkMethodName, true);
>+  }
>+
>+  /**
>+   * 
>+   * @param object The object to invoke the method on.
>+   * @param checkMethodName The name of the check method which returns a 
>boolean value.
>+   * @param expectedValue The expected value to be returned for the check to 
>be enabled.
>+   */
>+  public BooleanPropertyEnableCheck(final Object object, final String 
>checkMethodName, final boolean expectedValue) {
>+    Class clazz = object.getClass();
>+    this.object = object;
>+    this.expectedValue = expectedValue;
>+    try {
>+      method = clazz.getMethod(checkMethodName, new Class[] {});
>+    } catch (Throwable e) {
>+      throw new IllegalArgumentException("Unable to get check method "
>+        + checkMethodName + " on " + clazz);
>+    }
>+  }
>+
>+  public String check(JComponent component) {
>+    try {
>+      Boolean result = (Boolean)method.invoke(object, new Object[0]);
>+      if (result.booleanValue() == expectedValue) {
>+        return null;
>+      } else {
>+        return disabledMessage;
>+      }
>+    } catch (Throwable e) {
>+      e.printStackTrace();
>+      return e.getMessage();
>+    }
>+  }
>+}
>Index: src/org/openjump/core/ui/builder/DateTimeUiBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/DateTimeUiBuilder.java
>diff -N src/org/openjump/core/ui/builder/DateTimeUiBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/DateTimeUiBuilder.java    1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,23 @@
>+package org.openjump.core.ui.builder;
>+
>+import java.text.DateFormat;
>+import java.text.SimpleDateFormat;
>+import java.util.Date;
>+
>+import com.vividsolutions.jump.workbench.ui.GUIUtil;
>+
>+public class DateTimeUiBuilder extends AbstractUiBuilder {
>+
>+  public void appendHtml(StringBuffer s, Object object) {
>+    if (object instanceof Date) {
>+      Date date = (Date)object;
>+      DateFormat format = getDateFormat();
>+      s.append(GUIUtil.escapeHTML(format.format(date), false, false));
>+    }
>+      
>+  }
>+
>+  protected DateFormat getDateFormat() {
>+    return SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM, 
>SimpleDateFormat.MEDIUM);
>+  }
>+}
>Index: src/org/openjump/core/ui/builder/DateUIBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/DateUIBuilder.java
>diff -N src/org/openjump/core/ui/builder/DateUIBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/DateUIBuilder.java        1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,14 @@
>+package org.openjump.core.ui.builder;
>+
>+import java.text.DateFormat;
>+import java.text.SimpleDateFormat;
>+import java.util.Date;
>+
>+import com.vividsolutions.jump.workbench.ui.GUIUtil;
>+
>+public class DateUIBuilder extends DateTimeUiBuilder {
>+
>+  protected DateFormat getDateFormat() {
>+    return SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM);
>+  }
>+}
>Index: src/org/openjump/core/ui/builder/FeatureUiBuilder.java
>===================================================================
>RCS file: src/org/openjump/core/ui/builder/FeatureUiBuilder.java
>diff -N src/org/openjump/core/ui/builder/FeatureUiBuilder.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/org/openjump/core/ui/builder/FeatureUiBuilder.java     1 Jan 1970 
>00:00:00 -0000
>@@ -0,0 +1,114 @@
>+package org.openjump.core.ui.builder;
>+
>+import com.vividsolutions.jts.geom.Geometry;
>+import com.vividsolutions.jump.feature.Feature;
>+import com.vividsolutions.jump.feature.FeatureSchema;
>+import com.vividsolutions.jump.workbench.ui.GUIUtil;
>+
>+public class FeatureUiBuilder extends AbstractUiBuilder {
>+  private static final String TABLE_STYLE = "width: 100%;font-family: Tahoma, 
>Arial, sans-serif;font-size: 10pt;padding: 0px;border-collapse: collapse;";
>+
>+  private static final String TABLE_ATTRS = "style=\"" + TABLE_STYLE + "\" ";
>+
>+  private static final String TABLE_HEADING_STYLE = "vertical-align: 
>top;text-align: left;padding: 1px 2px;width: auto;";
>+
>+  private static final String TABLE_HEADING_ODD_ATTRS = 
>"style=\"background-color: #FFFFFF;"
>+    + TABLE_HEADING_STYLE + "\"";
>+
>+  private static final String TABLE_HEADING_EVEN_ATTRS = 
>"style=\"background-color: #E6E6E6;"
>+    + TABLE_HEADING_STYLE + "\"";
>+
>+  private static final String TABLE_CELL_STYLE = "vertical-align: 
>top;text-align: left;border-left: 1px solid black;padding: 0px;";
>+
>+  private static final String TABLE_CELL_ODD_ATTRS = 
>"style=\"background-color: #FFFFFF;"
>+    + TABLE_CELL_STYLE + "\"";
>+
>+  private static final String TABLE_CELL_EVEN_ATTRS = 
>"style=\"background-color: #E6E6E6;"
>+    + TABLE_CELL_STYLE + "\"";
>+
>+  private static final String SPAN_ATTRS = "style=\"padding: 1px 2px;\"";
>+
>+  private static final String TYPE_TITLE_ATTRS = "style=\"font-size: 
>12pt;font-weight:bold;padding: 1px 2px;background-color:#FFFFCC\"";
>+
>+  public FeatureUiBuilder() {
>+  }
>+
>+  public void appendHtml(StringBuffer s, Object object) {
>+    appendHtml(s, object, true);
>+  }
>+
>+  public void appendHtml(StringBuffer s, Object object, boolean nested) {
>+    if (object instanceof Feature) {
>+      Feature feature = (Feature)object;
>+      FeatureSchema schema = feature.getSchema();
>+      if (nested) {
>+        String schemaName = schema.getName();
>+        if (schemaName != null) {
>+          appendValue(s, schemaName, TYPE_TITLE_ATTRS);
>+        }
>+      }
>+      s.append("<table ").append(TABLE_ATTRS).append(">\n");
>+      boolean odd = true;
>+      if (!nested) {
>+        appendRow(s, true, "FID", String.valueOf(feature.getID()));
>+        odd = !odd;
>+      }
>+      for (int i = 0; i < schema.getAttributeCount(); i++) {
>+        Object value = feature.getAttribute(i);
>+        if (value instanceof Geometry) {
>+          continue;
>+        }
>+        String name = schema.getAttributeName(i);
>+        appendRow(s, odd, name, value);
>+        odd = !odd;
>+      }
>+      s.append("</table>\n");
>+    }
>+  }
>+
>+  private void appendRow(StringBuffer s, boolean odd, String name, Object 
>value) {
>+    if (odd) {
>+      s.append("<tr valign=\"top\" class=\"odd\"><th ").append(
>+        TABLE_HEADING_ODD_ATTRS).append(">");
>+    } else {
>+      s.append("<tr valign=\"top\" class=\"even\"><th ").append(
>+        TABLE_HEADING_EVEN_ATTRS).append(">");
>+    }
>+    appendEscaped(s, name);
>+    s.append("</th>\n");
>+    if (odd) {
>+      s.append("<td ").append(TABLE_CELL_ODD_ATTRS).append(">");
>+    } else {
>+      s.append("<td ").append(TABLE_CELL_EVEN_ATTRS).append(">");
>+    }
>+    appendValue(s, value);
>+    s.append("</td></tr>\n");
>+  }
>+
>+  private void appendValue(StringBuffer s, Object value) {
>+    String style = SPAN_ATTRS;
>+    s.append("<div>");
>+    if (value == null) {
>+      s.append("-");
>+    } else {
>+      String string = getRegistry().toHtml(value);
>+      s.append(string);
>+    }
>+    s.append("</div>");
>+  }
>+
>+  private void appendValue(StringBuffer s, String value, String style) {
>+    s.append("<div ").append(style).append(">");
>+    if (value == null) {
>+      s.append("-");
>+    } else {
>+      appendEscaped(s, value);
>+    }
>+    s.append("</div>");
>+  }
>+
>+  private void appendEscaped(StringBuffer s, String value) {
>+    s.append(GUIUtil.escapeHTML(value, false, false));
>+  }
>+
>+}
>Index: src/com/vividsolutions/jump/workbench/ui/swing/IconComponent.java
>===================================================================
>RCS file: src/com/vividsolutions/jump/workbench/ui/swing/IconComponent.java
>diff -N src/com/vividsolutions/jump/workbench/ui/swing/IconComponent.java
>--- /dev/null  1 Jan 1970 00:00:00 -0000
>+++ src/com/vividsolutions/jump/workbench/ui/swing/IconComponent.java  1 Jan 
>1970 00:00:00 -0000
>@@ -0,0 +1,10 @@
>+package com.vividsolutions.jump.workbench.ui.swing;
>+
>+import javax.swing.Icon;
>+
>+public interface IconComponent  {
>+  public Icon getIcon();
>+
>+  public void setIcon(Icon icon);
>+
>+}
>  
>
>------------------------------------------------------------------------
>
>-------------------------------------------------------------------------
>This SF.net email is sponsored by DB2 Express
>Download DB2 Express C - the FREE version of DB2 express and take
>control of your XML. No limits. Just data. Click to get it now.
>http://sourceforge.net/powerbar/db2/
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Jump-pilot-devel mailing list
>Jump-pilot-devel@lists.sourceforge.net
>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>  
>


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to