[Schmitzm-commits] r47 - in trunk/src: schmitzm/geotools/gui skrueger/geotools
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Apr 17 14:28:50 CEST 2009
Author: mojays
Date: 2009-04-17 14:28:50 +0200 (Fri, 17 Apr 2009)
New Revision: 47
Removed:
trunk/src/schmitzm/geotools/gui/FeatureCollectionPane.java
Modified:
trunk/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java
trunk/src/schmitzm/geotools/gui/FeatureCollectionFrame.java
trunk/src/schmitzm/geotools/gui/FeatureCollectionTableModel.java
trunk/src/schmitzm/geotools/gui/FeatureTablePane.java
trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java
Log:
- FeatureCollectionPane renamed to FeatureTablePane
- FeatureCollectionTableModel extracted to stand-alone class
Modified: trunk/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -53,7 +53,7 @@
public static final String TESTRESULT_LABEL = FeatureCollectionFilterPanel.class.getName()+".TestResultLabel";
/** Panel fuer Filter-Vorschau. */
- protected FeatureCollectionPane previewPanel = null;
+ protected FeatureTablePane previewPanel = null;
/** Button zum Testen der Formel */
protected JButton testButton = null;
/** Label mit Ergebnis des Formel-Tests */
@@ -118,7 +118,7 @@
// Label fuer Fehler-Meldungen
testResult = new JLabel("");
- previewPanel = new FeatureCollectionPane( null, geomPrev ) {
+ previewPanel = new FeatureTablePane( null, geomPrev ) {
// In der Tabelle sollen einzelne Werte selektiert werden koennen
// und diese bei einem Doppelklick in die Formel uebernommen werden
protected void initGUI(boolean geomPreview) {
Modified: trunk/src/schmitzm/geotools/gui/FeatureCollectionFrame.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/FeatureCollectionFrame.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/schmitzm/geotools/gui/FeatureCollectionFrame.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -17,7 +17,7 @@
import org.geotools.feature.FeatureCollection;
-import schmitzm.geotools.gui.FeatureCollectionPane;
+import schmitzm.geotools.gui.FeatureTablePane;
/**
* Dieses Fenster stellt eine {@link FeatureCollection} als Tabelle dar.
@@ -29,7 +29,7 @@
*/
public class FeatureCollectionFrame extends JFrame {
/** Enthaelt die Tabelle (und den Preview-Bereich). */
- protected FeatureCollectionPane featuresPane = null;
+ protected FeatureTablePane featuresPane = null;
/**
* Erzeugt ein neues Fenster inklusive Preview-Bereich fuer die in der
@@ -67,7 +67,7 @@
super();
this.setLayout( new BorderLayout() );
this.setDefaultCloseOperation( JFrame.HIDE_ON_CLOSE );
- this.featuresPane = new FeatureCollectionPane(fc,geomPreview);
+ this.featuresPane = new FeatureTablePane(fc,geomPreview);
this.getContentPane().add( featuresPane );
this.pack();
}
@@ -83,7 +83,7 @@
/**
* Liefert die angezeigte {@link FeatureCollection}.
*/
- public FeatureCollectionPane getFeatureCollectionPane() {
+ public FeatureTablePane getFeatureCollectionPane() {
return this.featuresPane;
}
}
Deleted: trunk/src/schmitzm/geotools/gui/FeatureCollectionPane.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/FeatureCollectionPane.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/schmitzm/geotools/gui/FeatureCollectionPane.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -1,456 +0,0 @@
-/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)
-
- This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
-
- Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
- Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
- Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
- **/
-
-package schmitzm.geotools.gui;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.event.MouseEvent;
-import java.util.Vector;
-
-import javax.swing.BorderFactory;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.event.TableModelEvent;
-import javax.swing.event.TableModelListener;
-import javax.swing.table.AbstractTableModel;
-import javax.swing.table.TableModel;
-
-import org.geotools.feature.AttributeType;
-import org.geotools.feature.Feature;
-import org.geotools.feature.FeatureCollection;
-import org.geotools.feature.FeatureCollections;
-import org.geotools.feature.FeatureIterator;
-import org.geotools.feature.FeatureType;
-import org.geotools.map.MapLayer;
-import org.geotools.styling.Style;
-
-import schmitzm.geotools.feature.AttributeTypeFilter;
-import schmitzm.geotools.feature.FeatureUtil;
-import schmitzm.swing.JPanel;
-import schmitzm.swing.MultiSplitPane;
-import schmitzm.swing.SwingUtil;
-
-/**
- * Diese Komponente stellt eine Tabelle dar, in der die Attribute einer
- * {@link FeatureCollection} dargestellt werden. Optional werden links neben der
- * Tabelle die in der Tabelle ausgewaehlten Features grafisch dargestellt.<br>
- * <br>
- * <b>Bemerkung:</b><br>
- * Als {@code TableModel} fuer die Feature-Tabelle verwendet diese Klasse
- * ein eigenes internes {@link TableModel}, welches effizienter arbeitet,
- * als {@link org.geotools.gui.swing.table.FeatureTableModel org.geotools.gui.swing.table.FeatureTableModel}.
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
- * @version 1.0
- */
-public class FeatureCollectionPane extends JPanel {
- /** Tabelle in der die Features angezeigt werden. */
- protected JTable featuresTable = null;
- /** Tabellen-Modell der Feature-Tabelle. */
- protected FeatureCollectionTableModel featuresTableModel = null;
- /** Preview-Bereich fuer die in der Tabelle selektierten Features. */
- protected JMapPane mapPane = null;
- /** Style, in dem die Features in der Karte dargestellt werden */
- protected Style featureStyle = null;
-
- /**
- * Erzeugt einen neue Komponente mit Preview-Bereich.
- */
- public FeatureCollectionPane() {
- this(false);
- }
-
- /**
- * Erzeugt einen neue Komponente mit Preview-Bereich.
- * @param fc angezeigte Features
- */
- public FeatureCollectionPane(FeatureCollection fc) {
- this(fc,true);
- }
-
- /**
- * Erzeugt einen neue Komponente.
- * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
- * oder nicht ({@code false})
- */
- public FeatureCollectionPane(boolean geomPreview) {
- this(null,geomPreview);
- }
-
- /**
- * Erzeugt einen neue Komponente.
- * @param fc angezeigte Features
- * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
- * oder nicht ({@code false})
- */
- public FeatureCollectionPane(FeatureCollection fc, boolean geomPreview) {
- this(fc,null,geomPreview);
- }
-
- /**
- * Erzeugt einen neue Komponente.
- * @param fc angezeigte Features
- * @param style Style, in dem die Features in der Karte dargestellt werden
- * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
- * oder nicht ({@code false})
- */
- public FeatureCollectionPane(FeatureCollection fc, Style style, boolean geomPreview) {
- super();
- this.featureStyle = style;
-
- initGUI( geomPreview );
-
- JScrollPane featuresTableScrollPane = new JScrollPane(
- featuresTable,
- JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
- JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
- );
-
- // Komponenten dem Pane hinzufuegen
- if ( mapPane != null ) {
- MultiSplitPane splitPane = new MultiSplitPane(2,JSplitPane.HORIZONTAL_SPLIT);
- splitPane.setInnerBorder(null);
- splitPane.setContainer(0,mapPane);
- splitPane.setContainer(1,featuresTableScrollPane);
- splitPane.setResizeWeigth( new double[] {0.2,0.8} );
- add(splitPane);
- } else {
- add(featuresTableScrollPane);
- }
- setFeatureCollection( fc );
- }
-
- /**
- * Initalisiert die GUI.
- * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
- * oder nicht ({@code false})
- */
- protected void initGUI(boolean geomPreview ) {
- setLayout( new BorderLayout() );
- // MapPane fuer Preview der in der Tabelle selektieren Features
- if ( geomPreview ) {
- this.mapPane = new JMapPane() {
- // Bei Links-Klick auf das gesamte Layer zoomen
- public void mouseClicked(MouseEvent e) {
- if (getState() == JMapPane.RESET && e.getButton() == e.BUTTON1) {
- MapLayer layer = getTopLayer();
- if (layer != null)
- try {
- setMapArea(layer.getFeatureSource().getBounds());
- refresh();
- } catch (Exception err) {
- }
- } else {
- super.mouseClicked(e);
- }
- }
- };
- mapPane.setState(JMapPane.RESET);
- mapPane.setWindowSelectionState(JMapPane.NONE);
- mapPane.setHighlight(false);
- mapPane.setMinimumSize(new Dimension(50, 50));
- SwingUtil.setPreferredWidth(mapPane,100);
- mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
- }
-
- // Tabelle fuer FeatureCollection
- featuresTableModel = new FeatureCollectionTableModel();
- featuresTable = new JTable(featuresTableModel);
- featuresTable.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
- featuresTable.setColumnSelectionAllowed(false);
- featuresTable.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
- // Wenn Auswahl in Tabelle sich aendert, Vorschau anpassen
- featuresTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
- public void valueChanged(ListSelectionEvent e) {
- performListSelection();
- }
- } );
- // Wenn neue FeatureCollection gesetzt wird, alle Features
- // in Vorschau anzeigen
- featuresTableModel.addTableModelListener( new TableModelListener() {
- public void tableChanged(TableModelEvent e) {
- showFeaturesInMap( getFeatureCollection() );
- }
- } );
- }
-
- /**
- * Liefert den Filter, der die dargestellten Attribut-Spalten bestimmt.
- */
- public AttributeTypeFilter getAttributeFilter() {
- return featuresTableModel.getAttributeFilter();
- }
-
- /**
- * Setzt den Filter, der die dargestellten Attribut-Spalten bestimmt.
- * @param attrFilter Filter
- */
- public void setAttributeFilter(AttributeTypeFilter attrFilter) {
- featuresTableModel.setAttributeFilter(attrFilter);
- }
-
- /**
- * Prueft, ob der Geometry-Preview angezeigt wird.
- */
- public boolean isGeometryPreviewVisible() {
- return mapPane.isVisible();
- }
-
- /**
- * Setzt die angezeigte {@link FeatureCollection}
- * @param fc anzuzeigende Features
- */
- public void setFeatureCollection(FeatureCollection fc) {
- featuresTableModel.setFeatureCollection(fc);
- }
-
- /**
- * Liefert die angezeigten Features.
- */
- public FeatureCollection getFeatureCollection() {
- return featuresTableModel.getFeatureCollection();
- }
-
- /**
- * Setzt den Style, in dem die Features in der Karte dargestellt werden.
- * @param style Style fuer die Features
- */
- public void setFeatureStyle( Style style ) {
- this.featureStyle = style;
- }
-
- /**
- * Liefert den Style, in dem die Features in der Karte dargestellt werden.
- */
- public Style getFeatureStyle() {
- return this.featureStyle;
- }
-
- /**
- * Liefert die in der Tabelle selektierten Features.
- */
- public FeatureCollection getSelectedFeatures() {
- return featuresTableModel.getFeaturesAsCollection( featuresTable.getSelectedRows() );
- }
-
- /**
- * Zeigt die aktuell in der Tabelle selektierten Features im Preview-Bereich an.
- */
- protected void performListSelection() {
- FeatureCollection subCollection = getSelectedFeatures();
- // Wenn keine Auswahl getaetigt ist, alle Features anzeigen
- if (subCollection == null || subCollection.isEmpty() )
- subCollection = getFeatureCollection();
- showFeaturesInMap( subCollection );
- }
-
- /**
- * Zeigt einen {@link FeatureCollection} in der Karte an. Diese Funktion
- * hat keinen Einfluss auf die in der Tabelle angezeigten Features!!
- * @param fc eine {@link FeatureCollection}
- */
- protected void showFeaturesInMap(FeatureCollection fc) {
- if ( mapPane == null )
- return;
- mapPane.getContext().clearLayerList();
- if ( fc != null && fc.size() > 0 && fc.getSchema().getDefaultGeometry() != null ) {
- if ( getFeatureStyle() == null )
- setFeatureStyle( FeatureUtil.createDefaultStyle(fc) );
- mapPane.getContext().addLayer(fc, getFeatureStyle() );
- mapPane.setMapArea(fc.getBounds());
- }
- mapPane.refresh();
- }
-
-
- /**
- * Tabellen-Modell fuer eine FeatureCollection. Aus Effizienzgruenden
- * (um wahlfreien Zugriff zu erreichen) werden die Features beim Aufruf von
- * {@link #setFeatureCollection(FeatureCollection)} in ein Array kopiert.
- * Veraenderungen an der zugrunde liegenden {@link FeatureCollection} werden
- * somit nicht automatisch in das Tabellen-Modell uebernommen, sondern es ist
- * ein expliziter Aufruf von {@link #reorganize()} notwendig.<br>
- * Bis zu diesem Punkt arbeitet diese Tabellen-Modell identisch zum
- * {@code FeatureTableModel} von Geotools. Im Gegensatz zu
- * {@link org.geotools.gui.swing.table.FeatureTableModel org.geotools.gui.swing.table.FeatureTableModel}.
- * werden die Tabellennamen und die Anzahl an Spalten jedoch nicht bei jedem Zugriff
- * neu aus dem ersten Feature ermittelt, sondern global gespeichert. Dies ist
- * erffizienter, da das haeufige Oeffnen eines {@link FeatureIterator FeatureIterators}
- * vermieden wird.
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
- * @version 1.0
- */
- protected static class FeatureCollectionTableModel extends AbstractTableModel {
- /** Holds the feature table that will be represented by this model. */
- protected FeatureCollection featureTable = null;
- /** Array mit den Daten von {@link #featureTable}. Wird nur beim Aufruf von
- * {@link #reorganize} befuellt. */
- protected Feature[] featureArray;
- /** Spaltennamen. Wird nur beim Aufruf von {@link #reorganize} befuellt. */
- protected String[] colNames = null;
- /** Bestimmt die angezeigten Features */
- protected AttributeTypeFilter attrFilter = AttributeTypeFilter.ALL;
-
- /** Speichert die angezeigten Attribut-Typen. */
- protected Vector<AttributeType> attrTypes = new Vector<AttributeType>();
- /** Speichert den Attribut-Index fuer jede Spalte (wichtig, wenn nicht
- * alle Spalten angezeigt werden!) */
- protected int[] attrIdxForCol = null;
-
- /**
- * Erzeugt ein neues (leeres) Tabellen-Modell.
- */
- public FeatureCollectionTableModel() {
- this(null);
- }
-
- /**
- * Erzeugt ein neues Tabellen-Modell.
- * @param features Daten fuer die Tabelle
- */
- public FeatureCollectionTableModel(final FeatureCollection features) {
- super();
- setFeatureCollection(features);
- }
-
- /**
- * Baut die interne Datenbasis (Array) des Tabellen-Modells neu auf.
- * Muss aufgerufen werden, damit nachtraegliche Aenderungen an der
- * zugrunde liegenden {@link FeatureCollection} in das Tabellenmodell
- * uebernommen werden.
- */
- public void reorganize() {
- featureArray = FeatureUtil.featuresToArray(featureTable);
- if ( featureArray == null || featureArray.length == 0 )
- colNames = new String[0];
- else {
- // Struktur der Tabelle von erstem Feature uebernehmen
- FeatureType ft = featureArray[0].getFeatureType();
- // Pruefen, welche Attribute angezeigt werden
- attrTypes.clear();
- for (int i=0; i<ft.getAttributeCount(); i++) {
- AttributeType type = ft.getAttributeType(i);
- if ( attrFilter == null || attrFilter.accept( type, i ) )
- attrTypes.add( type );
- }
- // Namen und Attribut-Indizes der angezeigten Spalten ermitteln
- colNames = new String[ attrTypes.size() ];
- attrIdxForCol = new int[ attrTypes.size() ];
- for (int i=0; i<colNames.length; i++) {
- int idx = ft.find( attrTypes.elementAt(i) );
- attrIdxForCol[i] = idx;
- colNames[i] = ft.getAttributeType(idx).getName();
- }
- }
- fireTableStructureChanged();
- }
-
- /**
- * Setzt die FeatureCollection fuer das Tabellen-Modell.
- * Ruft {@link #reorganize} auf.<br>
- * Nachtraegliche Aenderungen an der {@link FeatureCollection} werden
- * erst nach erneutem {@link #reorganize()} in das Tabellen-Modell uebernommen!
- * @param features Daten-Basis fuer die Tabelle
- */
- public void setFeatureCollection(final FeatureCollection features) {
- featureTable = features;
- reorganize();
- }
-
- /**
- * Liefert die FeatureCollection fuer das Tabellen-Modell.
- * Nachtraegliche Aenderungen an der {@link FeatureCollection} werden
- * erst nach erneutem {@link #reorganize()} in das Tabellen-Modell uebernommen!
- */
- public FeatureCollection getFeatureCollection() {
- return featureTable;
- }
-
- /**
- * Liefert den Filter, der die dargestellten Attribut-Spalten bestimmt.
- */
- public AttributeTypeFilter getAttributeFilter() {
- return attrFilter;
- }
-
- /**
- * Setzt den Filter, der die dargestellten Attribut-Spalten bestimmt.
- * @param attrFilter Filter
- */
- public void setAttributeFilter(AttributeTypeFilter attrFilter) {
- this.attrFilter = attrFilter;
- // Filter neu anwenden
- reorganize();
- }
-
- /**
- * Liefert die Anzahl an Spalten der Tabelle. Entspricht der Anzahl an
- * Attributen der Features.
- */
- public int getColumnCount() {
- return colNames == null ? 0 : colNames.length;
- }
-
- /**
- * Liefert einen Spaltennamen der Tabelle. Entspricht den Attributnamen
- * des (ersten) Features der Collection.
- * @param col Spalten-Index, beginnend bei 0
- */
- public String getColumnName(int col) {
- return colNames == null || col >= colNames.length ? "" : colNames[col];
- }
-
- /**
- * Liefert die Anzahl an Zeilen der Tabelle. Entspricht der Anzahl an
- * Features in der Collection.
- */
- public int getRowCount() {
- return featureTable == null ? 0 : featureTable.size();
- }
-
- /**
- * Liefert eine Zellen-Wert.
- * @param row Zeilennummer (Feature), beginnend bei 0
- * @param col Spaltennummer (Attribut), beginnen bei 0
- */
- public Object getValueAt(final int row, final int col) {
- if (featureArray == null)
- featureArray = FeatureUtil.featuresToArray(featureTable);
- return featureArray[row].getAttribute( attrIdxForCol[col] );
- }
-
- /**
- * Liefert Features der Tabelle als Array.
- * @param idx Indizes der FeatureCollection
- */
- public Feature[] getFeaturesAsArray(int[] idx) {
- Feature[] features = new Feature[ idx == null ? 0 : idx.length ];
- for (int i=0; i<features.length; i++)
- features[i] = featureArray[ idx[i] ];
- return features;
- }
-
- /**
- * Liefert Features der Tabelle als Collection.
- * @param idx Indizes der FeatureCollection
- */
- public FeatureCollection getFeaturesAsCollection(int[] idx) {
- FeatureCollection featureCol = FeatureCollections.newCollection();
- for (int i=0; idx != null && i<idx.length; i++)
- featureCol.add( featureArray[ idx[i] ] );
- return featureCol;
- }
- }
-}
Modified: trunk/src/schmitzm/geotools/gui/FeatureCollectionTableModel.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/FeatureCollectionTableModel.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/schmitzm/geotools/gui/FeatureCollectionTableModel.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -1,31 +1,204 @@
+/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)
+
+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+ Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+ Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+ Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
package schmitzm.geotools.gui;
+import java.util.Vector;
+
import org.geotools.data.FeatureSource;
+import org.geotools.feature.AttributeType;
+import org.geotools.feature.Feature;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureCollections;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.FeatureType;
-import schmitzm.swing.table.AbstractTableModel;
+import schmitzm.geotools.feature.AttributeTypeFilter;
+import schmitzm.geotools.feature.FeatureUtil;
+import javax.swing.table.AbstractTableModel;
+/**
+ * Tabellen-Modell fuer eine FeatureCollection. Aus Effizienzgruenden
+ * (um wahlfreien Zugriff zu erreichen) werden die Features beim Aufruf von
+ * {@link #setFeatureCollection(FeatureCollection)} in ein Array kopiert.
+ * Veraenderungen an der zugrunde liegenden {@link FeatureCollection} werden
+ * somit nicht automatisch in das Tabellen-Modell uebernommen, sondern es ist
+ * ein expliziter Aufruf von {@link #reorganize()} notwendig.<br>
+ * Bis zu diesem Punkt arbeitet diese Tabellen-Modell identisch zum
+ * {@code FeatureTableModel} von Geotools. Im Gegensatz zu
+ * {@link org.geotools.gui.swing.table.FeatureTableModel org.geotools.gui.swing.table.FeatureTableModel}.
+ * werden die Tabellennamen und die Anzahl an Spalten jedoch nicht bei jedem Zugriff
+ * neu aus dem ersten Feature ermittelt, sondern global gespeichert. Dies ist
+ * erffizienter, da das haeufige Oeffnen eines {@link FeatureIterator FeatureIterators}
+ * vermieden wird.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
public class FeatureCollectionTableModel extends AbstractTableModel {
+ /** Holds the feature table that will be represented by this model. */
+ protected FeatureCollection featureTable = null;
+ /** Array mit den Daten von {@link #featureTable}. Wird nur beim Aufruf von
+ * {@link #reorganize} befuellt. */
+ protected Feature[] featureArray;
+ /** Spaltennamen. Wird nur beim Aufruf von {@link #reorganize} befuellt. */
+ protected String[] colNames = null;
+ /** Bestimmt die angezeigten Features */
+ protected AttributeTypeFilter attrFilter = AttributeTypeFilter.ALL;
- public FeatureCollectionTableModel(FeatureSource source) {
-
+ /** Speichert die angezeigten Attribut-Typen. */
+ protected Vector<AttributeType> attrTypes = new Vector<AttributeType>();
+ /** Speichert den Attribut-Index fuer jede Spalte (wichtig, wenn nicht
+ * alle Spalten angezeigt werden!) */
+ protected int[] attrIdxForCol = null;
+
+ /**
+ * Erzeugt ein neues (leeres) Tabellen-Modell.
+ */
+ public FeatureCollectionTableModel() {
+ this(null);
}
-
- @Override
- public String[] createColumnNames() {
- // TODO Auto-generated method stub
- return null;
+
+ /**
+ * Erzeugt ein neues Tabellen-Modell.
+ * @param features Daten fuer die Tabelle
+ */
+ public FeatureCollectionTableModel(final FeatureCollection features) {
+ super();
+ setFeatureCollection(features);
}
- @Override
+ /**
+ * Baut die interne Datenbasis (Array) des Tabellen-Modells neu auf.
+ * Muss aufgerufen werden, damit nachtraegliche Aenderungen an der
+ * zugrunde liegenden {@link FeatureCollection} in das Tabellenmodell
+ * uebernommen werden.
+ */
+ public void reorganize() {
+ featureArray = FeatureUtil.featuresToArray(featureTable);
+ if ( featureArray == null || featureArray.length == 0 )
+ colNames = new String[0];
+ else {
+ // Struktur der Tabelle von erstem Feature uebernehmen
+ FeatureType ft = featureArray[0].getFeatureType();
+ // Pruefen, welche Attribute angezeigt werden
+ attrTypes.clear();
+ for (int i=0; i<ft.getAttributeCount(); i++) {
+ AttributeType type = ft.getAttributeType(i);
+ if ( attrFilter == null || attrFilter.accept( type, i ) )
+ attrTypes.add( type );
+ }
+ // Namen und Attribut-Indizes der angezeigten Spalten ermitteln
+ colNames = new String[ attrTypes.size() ];
+ attrIdxForCol = new int[ attrTypes.size() ];
+ for (int i=0; i<colNames.length; i++) {
+ int idx = ft.find( attrTypes.elementAt(i) );
+ attrIdxForCol[i] = idx;
+ colNames[i] = ft.getAttributeType(idx).getLocalName();
+ }
+ }
+ fireTableStructureChanged();
+ }
+
+ /**
+ * Setzt die FeatureCollection fuer das Tabellen-Modell.
+ * Ruft {@link #reorganize} auf.<br>
+ * Nachtraegliche Aenderungen an der {@link FeatureCollection} werden
+ * erst nach erneutem {@link #reorganize()} in das Tabellen-Modell uebernommen!
+ * @param features Daten-Basis fuer die Tabelle
+ */
+ public void setFeatureCollection(final FeatureCollection features) {
+ featureTable = features;
+ reorganize();
+ }
+
+ /**
+ * Liefert die FeatureCollection fuer das Tabellen-Modell.
+ * Nachtraegliche Aenderungen an der {@link FeatureCollection} werden
+ * erst nach erneutem {@link #reorganize()} in das Tabellen-Modell uebernommen!
+ */
+ public FeatureCollection getFeatureCollection() {
+ return featureTable;
+ }
+
+ /**
+ * Liefert den Filter, der die dargestellten Attribut-Spalten bestimmt.
+ */
+ public AttributeTypeFilter getAttributeFilter() {
+ return attrFilter;
+ }
+
+ /**
+ * Setzt den Filter, der die dargestellten Attribut-Spalten bestimmt.
+ * @param attrFilter Filter
+ */
+ public void setAttributeFilter(AttributeTypeFilter attrFilter) {
+ this.attrFilter = attrFilter;
+ // Filter neu anwenden
+ reorganize();
+ }
+
+ /**
+ * Liefert die Anzahl an Spalten der Tabelle. Entspricht der Anzahl an
+ * Attributen der Features.
+ */
+ public int getColumnCount() {
+ return colNames == null ? 0 : colNames.length;
+ }
+
+ /**
+ * Liefert einen Spaltennamen der Tabelle. Entspricht den Attributnamen
+ * des (ersten) Features der Collection.
+ * @param col Spalten-Index, beginnend bei 0
+ */
+ public String getColumnName(int col) {
+ return colNames == null || col >= colNames.length ? "" : colNames[col];
+ }
+
+ /**
+ * Liefert die Anzahl an Zeilen der Tabelle. Entspricht der Anzahl an
+ * Features in der Collection.
+ */
public int getRowCount() {
- // TODO Auto-generated method stub
- return 0;
+ return featureTable == null ? 0 : featureTable.size();
}
- @Override
- public Object getValueAt(int arg0, int arg1) {
- // TODO Auto-generated method stub
- return null;
+ /**
+ * Liefert eine Zellen-Wert.
+ * @param row Zeilennummer (Feature), beginnend bei 0
+ * @param col Spaltennummer (Attribut), beginnen bei 0
+ */
+ public Object getValueAt(final int row, final int col) {
+ if (featureArray == null)
+ featureArray = FeatureUtil.featuresToArray(featureTable);
+ return featureArray[row].getAttribute( attrIdxForCol[col] );
}
+ /**
+ * Liefert Features der Tabelle als Array.
+ * @param idx Indizes der FeatureCollection
+ */
+ public Feature[] getFeaturesAsArray(int[] idx) {
+ Feature[] features = new Feature[ idx == null ? 0 : idx.length ];
+ for (int i=0; i<features.length; i++)
+ features[i] = featureArray[ idx[i] ];
+ return features;
+ }
+
+ /**
+ * Liefert Features der Tabelle als Collection.
+ * @param idx Indizes der FeatureCollection
+ */
+ public FeatureCollection getFeaturesAsCollection(int[] idx) {
+ FeatureCollection featureCol = FeatureCollections.newCollection();
+ for (int i=0; idx != null && i<idx.length; i++)
+ featureCol.add( featureArray[ idx[i] ] );
+ return featureCol;
+ }
}
Modified: trunk/src/schmitzm/geotools/gui/FeatureTablePane.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/FeatureTablePane.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/schmitzm/geotools/gui/FeatureTablePane.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -1,9 +1,287 @@
+/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)
+
+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+ Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+ Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+ Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
+/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)
+
+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+ Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+ Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+ Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
+
package schmitzm.geotools.gui;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.MouseEvent;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+import org.geotools.feature.AttributeType;
+import org.geotools.feature.Feature;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureCollections;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.FeatureType;
+import org.geotools.map.MapLayer;
+import org.geotools.styling.Style;
+
+import schmitzm.geotools.feature.AttributeTypeFilter;
+import schmitzm.geotools.feature.FeatureUtil;
import schmitzm.swing.JPanel;
+import schmitzm.swing.MultiSplitPane;
+import schmitzm.swing.SwingUtil;
+/**
+ * Diese Komponente stellt eine Tabelle dar, in der die Attribute einer
+ * {@link FeatureCollection} dargestellt werden. Optional werden links neben der
+ * Tabelle die in der Tabelle ausgewaehlten Features grafisch dargestellt.<br>
+ * <br>
+ * <b>Bemerkung:</b><br>
+ * Als {@code TableModel} fuer die Feature-Tabelle verwendet diese Klasse
+ * ein eigenes internes {@link TableModel}, welches effizienter arbeitet,
+ * als {@link org.geotools.gui.swing.table.FeatureTableModel org.geotools.gui.swing.table.FeatureTableModel}.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
public class FeatureTablePane extends JPanel {
- public FeatureTablePane(FeatureCollectionTableModel model) {
-
+ /** Tabelle in der die Features angezeigt werden. */
+ protected JTable featuresTable = null;
+ /** Tabellen-Modell der Feature-Tabelle. */
+ protected FeatureCollectionTableModel featuresTableModel = null;
+ /** Preview-Bereich fuer die in der Tabelle selektierten Features. */
+ protected JMapPane mapPane = null;
+ /** Style, in dem die Features in der Karte dargestellt werden */
+ protected Style featureStyle = null;
+
+ /**
+ * Erzeugt einen neue Komponente mit Preview-Bereich.
+ */
+ public FeatureTablePane() {
+ this(false);
}
+
+ /**
+ * Erzeugt einen neue Komponente mit Preview-Bereich.
+ * @param fc angezeigte Features
+ */
+ public FeatureTablePane(FeatureCollection fc) {
+ this(fc,true);
+ }
+
+ /**
+ * Erzeugt einen neue Komponente.
+ * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
+ * oder nicht ({@code false})
+ */
+ public FeatureTablePane(boolean geomPreview) {
+ this(null,geomPreview);
+ }
+
+ /**
+ * Erzeugt einen neue Komponente.
+ * @param fc angezeigte Features
+ * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
+ * oder nicht ({@code false})
+ */
+ public FeatureTablePane(FeatureCollection fc, boolean geomPreview) {
+ this(fc,null,geomPreview);
+ }
+
+ /**
+ * Erzeugt einen neue Komponente.
+ * @param fc angezeigte Features
+ * @param style Style, in dem die Features in der Karte dargestellt werden
+ * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
+ * oder nicht ({@code false})
+ */
+ public FeatureTablePane(FeatureCollection fc, Style style, boolean geomPreview) {
+ super();
+ this.featureStyle = style;
+
+ initGUI( geomPreview );
+
+ JScrollPane featuresTableScrollPane = new JScrollPane(
+ featuresTable,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
+ );
+
+ // Komponenten dem Pane hinzufuegen
+ if ( mapPane != null ) {
+ MultiSplitPane splitPane = new MultiSplitPane(2,JSplitPane.HORIZONTAL_SPLIT);
+ splitPane.setInnerBorder(null);
+ splitPane.setContainer(0,mapPane);
+ splitPane.setContainer(1,featuresTableScrollPane);
+ splitPane.setResizeWeigth( new double[] {0.2,0.8} );
+ add(splitPane);
+ } else {
+ add(featuresTableScrollPane);
+ }
+ setFeatureCollection( fc );
+ }
+
+ /**
+ * Initalisiert die GUI.
+ * @param geomPreview bestimmt, ob ein Preview-Bereich angezeigt wird ({@code true})
+ * oder nicht ({@code false})
+ */
+ protected void initGUI(boolean geomPreview ) {
+ setLayout( new BorderLayout() );
+ // MapPane fuer Preview der in der Tabelle selektieren Features
+ if ( geomPreview ) {
+ this.mapPane = new JMapPane() {
+ // Bei Links-Klick auf das gesamte Layer zoomen
+ public void mouseClicked(MouseEvent e) {
+ if (getState() == JMapPane.RESET && e.getButton() == e.BUTTON1) {
+ MapLayer layer = getTopLayer();
+ if (layer != null)
+ try {
+ setMapArea(layer.getFeatureSource().getBounds());
+ refresh();
+ } catch (Exception err) {
+ }
+ } else {
+ super.mouseClicked(e);
+ }
+ }
+ };
+ mapPane.setState(JMapPane.RESET);
+ mapPane.setWindowSelectionState(JMapPane.NONE);
+ mapPane.setHighlight(false);
+ mapPane.setMinimumSize(new Dimension(50, 50));
+ SwingUtil.setPreferredWidth(mapPane,100);
+ mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ }
+
+ // Tabelle fuer FeatureCollection
+ featuresTableModel = new FeatureCollectionTableModel();
+ featuresTable = new JTable(featuresTableModel);
+ featuresTable.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
+ featuresTable.setColumnSelectionAllowed(false);
+ featuresTable.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
+ // Wenn Auswahl in Tabelle sich aendert, Vorschau anpassen
+ featuresTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ performListSelection();
+ }
+ } );
+ // Wenn neue FeatureCollection gesetzt wird, alle Features
+ // in Vorschau anzeigen
+ featuresTableModel.addTableModelListener( new TableModelListener() {
+ public void tableChanged(TableModelEvent e) {
+ showFeaturesInMap( getFeatureCollection() );
+ }
+ } );
+ }
+
+ /**
+ * Liefert den Filter, der die dargestellten Attribut-Spalten bestimmt.
+ */
+ public AttributeTypeFilter getAttributeFilter() {
+ return featuresTableModel.getAttributeFilter();
+ }
+
+ /**
+ * Setzt den Filter, der die dargestellten Attribut-Spalten bestimmt.
+ * @param attrFilter Filter
+ */
+ public void setAttributeFilter(AttributeTypeFilter attrFilter) {
+ featuresTableModel.setAttributeFilter(attrFilter);
+ }
+
+ /**
+ * Prueft, ob der Geometry-Preview angezeigt wird.
+ */
+ public boolean isGeometryPreviewVisible() {
+ return mapPane.isVisible();
+ }
+
+ /**
+ * Setzt die angezeigte {@link FeatureCollection}
+ * @param fc anzuzeigende Features
+ */
+ public void setFeatureCollection(FeatureCollection fc) {
+ featuresTableModel.setFeatureCollection(fc);
+ }
+
+ /**
+ * Liefert die angezeigten Features.
+ */
+ public FeatureCollection getFeatureCollection() {
+ return featuresTableModel.getFeatureCollection();
+ }
+
+ /**
+ * Setzt den Style, in dem die Features in der Karte dargestellt werden.
+ * @param style Style fuer die Features
+ */
+ public void setFeatureStyle( Style style ) {
+ this.featureStyle = style;
+ }
+
+ /**
+ * Liefert den Style, in dem die Features in der Karte dargestellt werden.
+ */
+ public Style getFeatureStyle() {
+ return this.featureStyle;
+ }
+
+ /**
+ * Liefert die in der Tabelle selektierten Features.
+ */
+ public FeatureCollection getSelectedFeatures() {
+ return featuresTableModel.getFeaturesAsCollection( featuresTable.getSelectedRows() );
+ }
+
+ /**
+ * Zeigt die aktuell in der Tabelle selektierten Features im Preview-Bereich an.
+ */
+ protected void performListSelection() {
+ FeatureCollection subCollection = getSelectedFeatures();
+ // Wenn keine Auswahl getaetigt ist, alle Features anzeigen
+ if (subCollection == null || subCollection.isEmpty() )
+ subCollection = getFeatureCollection();
+ showFeaturesInMap( subCollection );
+ }
+
+ /**
+ * Zeigt einen {@link FeatureCollection} in der Karte an. Diese Funktion
+ * hat keinen Einfluss auf die in der Tabelle angezeigten Features!!
+ * @param fc eine {@link FeatureCollection}
+ */
+ protected void showFeaturesInMap(FeatureCollection fc) {
+ if ( mapPane == null )
+ return;
+ mapPane.getContext().clearLayerList();
+ if ( fc != null && fc.size() > 0 && fc.getSchema().getDefaultGeometry() != null ) {
+ if ( getFeatureStyle() == null )
+ setFeatureStyle( FeatureUtil.createDefaultStyle(fc) );
+ mapPane.getContext().addLayer(fc, getFeatureStyle() );
+ mapPane.setMapArea(fc.getBounds());
+ }
+ mapPane.refresh();
+ }
}
+
Modified: trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java
===================================================================
--- trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java 2009-04-17 11:44:05 UTC (rev 46)
+++ trunk/src/skrueger/geotools/StyledFeatureCollectionTableModel.java 2009-04-17 12:28:50 UTC (rev 47)
@@ -1,3 +1,13 @@
+/** SCHMITZM - This file is part of the java library of Martin O.J. Schmitz (SCHMITZM)
+
+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+ Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+ Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+ Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
package skrueger.geotools;
import schmitzm.geotools.gui.FeatureCollectionTableModel;
More information about the Schmitzm-commits
mailing list