[Schmitzm-commits] r1190 - in trunk: src/schmitzm/geotools/gui src/skrueger/swing src_junit/schmitzm/io src_junit/schmitzm/swing
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Sat Oct 30 00:03:21 CEST 2010
Author: alfonx
Date: 2010-10-30 00:03:19 +0200 (Sat, 30 Oct 2010)
New Revision: 1190
Added:
trunk/src/skrueger/swing/FilterTableKeyListener.java
Modified:
trunk/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java
trunk/src_junit/schmitzm/io/IOUtilTest.java
trunk/src_junit/schmitzm/swing/TestingUtil.java
Log:
Added new FilterTableKeyListener, which connects a JTextField with any JTable and allows to filter the list by content. The input is converted to OR. A timer can be set that delays(collects) the update of the JTable.
Modified: trunk/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java 2010-10-28 09:47:06 UTC (rev 1189)
+++ trunk/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java 2010-10-29 22:03:19 UTC (rev 1190)
@@ -30,7 +30,6 @@
package schmitzm.geotools.gui;
import java.awt.BorderLayout;
-import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
@@ -45,22 +44,26 @@
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
+import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.RowSorter.SortKey;
import javax.swing.SortOrder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
+import net.miginfocom.swing.MigLayout;
+
import org.geotools.feature.FeatureCollection;
import schmitzm.geotools.feature.FeatureUtil;
import schmitzm.swing.table.SelectionTableModel;
+import skrueger.swing.FilterTableKeyListener;
/**
* Extends the {@link FeatureTablePane} with buttons and functionality to select
- * lines. Can be configured to set the regions on an external a {@link SelectableXMapPane}
- * . Can be configured to show a simple preview {@link SelectableXMapPane} to the left of
- * the table.
+ * lines. Can be configured to set the regions on an external a
+ * {@link SelectableXMapPane} . Can be configured to show a simple preview
+ * {@link SelectableXMapPane} to the left of the table.
*
* @author Stefan A. Tzeggai
*
@@ -70,53 +73,55 @@
public static final ImageIcon ICON_SELECTION_INVERT = new ImageIcon(
SelectableFeatureTablePane.class
.getResource("resource/icons/mActionInvertSelection.png"));
-
+
public static final ImageIcon ICON_SELECTED_TO_TOP = new ImageIcon(
SelectableFeatureTablePane.class
.getResource("resource/icons/mActionSelectedToTop.png"));
-
+
public static final ImageIcon ICON_UNSELECT = new ImageIcon(
SelectableFeatureTablePane.class
.getResource("resource/icons/mActionUnselectAttributes.png"));
-
+
public static final ImageIcon ICON_ZOOM_TO_SELECTED = new ImageIcon(
SelectableFeatureTablePane.class
.getResource("resource/icons/mActionZoomToSelected.png"));
-
-
+
private final SelectableXMapPane externalMapPane;
-
+
private JLabel statusLabel;
- /**
- * @param fc
- * {@link FeatureCollection} that holds the data.
- * @param geomPreview
- * If <code>true</code>, a preview {@link SelectableXMapPane} is attached
- * to the left of the table.
- * @param externalMapPane
- * <code>null</code> if this component is NOT linked to an
- * external JMapPane. If mapPane == <code>null</code>, the
- * "ZoomToSelection" Button is automatically disabled. If a
- * {@link SelectableXMapPane} is passed, the "ZoomToSelectedFeature"
- * function will be enabled.
- */
- public SelectableFeatureTablePane(FeatureCollection fc, boolean geomPreview, SelectableXMapPane externalMapPane) {
- this(new FeatureCollectionTableModel(fc), geomPreview, externalMapPane);
- }
+ private JPanel sarchPanel;
- /**
+ /**
+ * @param fc
+ * {@link FeatureCollection} that holds the data.
+ * @param geomPreview
+ * If <code>true</code>, a preview {@link SelectableXMapPane} is
+ * attached to the left of the table.
+ * @param externalMapPane
+ * <code>null</code> if this component is NOT linked to an
+ * external JMapPane. If mapPane == <code>null</code>, the
+ * "ZoomToSelection" Button is automatically disabled. If a
+ * {@link SelectableXMapPane} is passed, the
+ * "ZoomToSelectedFeature" function will be enabled.
+ */
+ public SelectableFeatureTablePane(FeatureCollection fc,
+ boolean geomPreview, SelectableXMapPane externalMapPane) {
+ this(new FeatureCollectionTableModel(fc), geomPreview, externalMapPane);
+ }
+
+ /**
* @param model
* {@link FeatureCollectionTableModel} that holds the data.
* @param geomPreview
- * If <code>true</code>, a preview {@link SelectableXMapPane} is attached
- * to the left of the table.
+ * If <code>true</code>, a preview {@link SelectableXMapPane} is
+ * attached to the left of the table.
* @param externalMapPane
* <code>null</code> if this component is NOT linked to an
* external JMapPane. If mapPane == <code>null</code>, the
* "ZoomToSelection" Button is automatically disabled. If a
- * {@link SelectableXMapPane} is passed, the "ZoomToSelectedFeature"
- * function will be enabled.
+ * {@link SelectableXMapPane} is passed, the
+ * "ZoomToSelectedFeature" function will be enabled.
*/
public SelectableFeatureTablePane(FeatureCollectionTableModel model,
boolean geomPreview, SelectableXMapPane externalMapPane) {
@@ -130,7 +135,9 @@
newPanelArroundTable.add(splitPane.getRightComponent(),
BorderLayout.CENTER);
splitPane.setRightComponent(newPanelArroundTable);
- splitPane.setDividerLocation(0.33); // SK: Does have no effect because the JSplitPane is not yet rendered.
+ splitPane.setDividerLocation(0.33); // SK: Does have no effect
+ // because the JSplitPane is not
+ // yet rendered.
} else {
newPanelArroundTable.add(getComponent(0), BorderLayout.CENTER);
removeAll();
@@ -139,78 +146,106 @@
// Change the sizes
mapPane.setPreferredSize(new Dimension(200, 300));
-
+
featuresTable.getParent().setPreferredSize(new Dimension(400, 300));
- featuresTable.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
+ featuresTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
- // In the NORTH, the ToolBar and a JLabel presenting the total and selected number of features is displayed
+ // In the NORTH, the ToolBar and a JLabel presenting the total and
+ // selected number of features is displayed
JPanel north = new JPanel(new BorderLayout());
north.add(getToolBar(), BorderLayout.WEST);
north.add(getStatusLabel(), BorderLayout.EAST);
newPanelArroundTable.add(north, BorderLayout.NORTH);
newPanelArroundTable.add(getSearchBar(), BorderLayout.SOUTH);
-
- featuresTable.getSelectionModel().addListSelectionListener( new ListSelectionListener(){
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if (!e.getValueIsAdjusting()){
- getStatusLabel();
- }
- }
-
- });
+ featuresTable.getSelectionModel().addListSelectionListener(
+ new ListSelectionListener() {
+
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ if (!e.getValueIsAdjusting()) {
+ getStatusLabel();
+ }
+ }
+
+ });
}
/**
- * After calling the super-method the table model is encapsulated in
- * a {@link SelectionTableModel} to show a selection column.
+ * After calling the super-method the table model is encapsulated in a
+ * {@link SelectionTableModel} to show a selection column.
*/
- @Override
- protected void initGUI(boolean geomPreview) {
- super.initGUI(geomPreview);
- // Reset the table model to show a selection column
- featuresTable.setModel( new SelectionTableModel(featuresTableModel, featuresTable) );
- // Because SortableJTable is used, the first col is always a checkbox.
- // TODO: How wide is a CheckBox in differnet L'n'F s?
- int selCol = featuresTable.convertColumnIndexToModel(0);
- featuresTable.getColumnModel().getColumn(selCol).setMaxWidth(17);
- }
-
- /**
- * This Label present something like "40 of 56 Polygons selected". It is lazily constructed. Later calls will only update the existing label.
+ @Override
+ protected void initGUI(boolean geomPreview) {
+ super.initGUI(geomPreview);
+ // Reset the table model to show a selection column
+ featuresTable.setModel(new SelectionTableModel(featuresTableModel,
+ featuresTable));
+ // Because SortableJTable is used, the first col is always a checkbox.
+ // TODO: How wide is a CheckBox in differnet L'n'F s?
+ int selCol = featuresTable.convertColumnIndexToModel(0);
+ featuresTable.getColumnModel().getColumn(selCol).setMaxWidth(17);
+ }
+
+ /**
+ * This Label present something like "40 of 56 Polygons selected". It is
+ * lazily constructed. Later calls will only update the existing label.
*/
private JLabel getStatusLabel() {
- if (statusLabel == null){
+ if (statusLabel == null) {
statusLabel = new JLabel();
}
-
+
int selectedAnz = getSelectedFeatures().size();
-
- // TODO Cache totalAnz and localizedGeometryTypeName. Do not recalc all the time!
+
+ // TODO Cache totalAnz and localizedGeometryTypeName. Do not recalc all
+ // the time!
int totalAnz = getFeatureCollection().size();
-
+
String localizedGeometryTypeName = "rows";
-
- switch ( FeatureUtil.getGeometryForm(getFeatureCollection()) ){
+
+ switch (FeatureUtil.getGeometryForm(getFeatureCollection())) {
case LINE:
- localizedGeometryTypeName = GeotoolsGUIUtil.R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.lines");
+ localizedGeometryTypeName = GeotoolsGUIUtil
+ .R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.lines");
break;
case POLYGON:
- localizedGeometryTypeName = GeotoolsGUIUtil.R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.polygons");
+ localizedGeometryTypeName = GeotoolsGUIUtil
+ .R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.polygons");
break;
case POINT:
- localizedGeometryTypeName = GeotoolsGUIUtil.R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.points");
+ localizedGeometryTypeName = GeotoolsGUIUtil
+ .R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus.points");
break;
}
-
- statusLabel.setText( GeotoolsGUIUtil.R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus", selectedAnz, totalAnz,localizedGeometryTypeName));
-
+
+ statusLabel
+ .setText(GeotoolsGUIUtil
+ .R("schmitzm.geotools.gui.SelectableFeatureTablePane.selectionStatus",
+ selectedAnz, totalAnz,
+ localizedGeometryTypeName));
+
return statusLabel;
}
- private Component getSearchBar() {
- return new JLabel(""); // TODO Add ability to search here!
+ /**
+ * Adding the ability to search all Field. The Key events are collected evry
+ * 1000ms for fast typers ;-).
+ */
+ private JPanel getSearchBar() {
+ if (sarchPanel == null) {
+ sarchPanel = new JPanel(new MigLayout("", "[grow]"));
+ sarchPanel.add(new JLabel("Filter:"), "align right");
+ JTextField filtertextField = new JTextField();
+
+ // The constructor adds itself to the textfield
+ // Use 1000ms delay, in case the table is large...
+ new FilterTableKeyListener(getTable(), 1000, filtertextField);
+
+ sarchPanel.add(filtertextField, " growx , align right");
+
+ }
+ return sarchPanel;
}
/**
@@ -218,9 +253,9 @@
*/
protected JToolBar getToolBar() {
JToolBar toolBar = new JToolBar();
-
- toolBar.setFloatable(false); // Sorry Martin ;-)
+ toolBar.setFloatable(false); // Sorry Martin ;-)
+
/**
* Add an Action to clear the selection
*/
@@ -262,7 +297,7 @@
keys.add(0, sortKey);
featuresTable.getRowSorter().setSortKeys(keys);
-
+
// Move the scrollbars to the top
JScrollPane scrollPane = getFeaturesTableScrollPane();
JScrollBar verticalScrollBar = scrollPane
@@ -272,7 +307,6 @@
verticalScrollBar.setValue(verticalScrollBar.getMinimum());
horizontalScrollBar.setValue(horizontalScrollBar.getMinimum());
-
// A bug? Sorting only works from the second time on..
if (isFirstClick) {
isFirstClick = false;
@@ -298,16 +332,16 @@
public void actionPerformed(ActionEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
+
featuresTable.getSelectionModel().setValueIsAdjusting(true);
-
+
for (int i = 0; i < featuresTable.getModel().getRowCount(); i++) {
if (featuresTable.getSelectionModel().isSelectedIndex(i)) {
- featuresTable.getSelectionModel().removeSelectionInterval(
+ featuresTable.getSelectionModel()
+ .removeSelectionInterval(i, i);
+ } else {
+ featuresTable.getSelectionModel().addSelectionInterval(
i, i);
- } else {
- featuresTable.getSelectionModel().addSelectionInterval(i,
- i);
}
}
featuresTable.getSelectionModel().setValueIsAdjusting(false);
Added: trunk/src/skrueger/swing/FilterTableKeyListener.java
===================================================================
--- trunk/src/skrueger/swing/FilterTableKeyListener.java 2010-10-28 09:47:06 UTC (rev 1189)
+++ trunk/src/skrueger/swing/FilterTableKeyListener.java 2010-10-29 22:03:19 UTC (rev 1190)
@@ -0,0 +1,110 @@
+package skrueger.swing;
+
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.regex.Pattern;
+
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.RowFilter;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableRowSorter;
+
+/**
+ * Connects a {@link JTextField} with a {@link JTable} to filter the data. The
+ * column it should filter are given as indices on construction.
+ *
+ */
+public class FilterTableKeyListener extends KeyAdapter {
+
+ private final JTable table;
+ private final int[] indices;
+ private final JTextField jTextField;
+ private Timer setRowFilterTimer;
+
+ /**
+ * Collects key events for 300ms, The constructor adds itself the the
+ * {@link JTextField}!
+ *
+ * @param table
+ * @param jTextField
+ * @param indices
+ */
+ public FilterTableKeyListener(JTable table, JTextField jTextField,
+ int... indices) {
+ this(table, 300, jTextField, indices);
+ }
+
+ /**
+ * The constructor adds itself the the {@link JTextField}!
+ *
+ * @param table
+ * @param jTextField
+ * @param waitToUpdateGuiMs
+ * ms to wait until the table rowSorter is changed.
+ * @param indices
+ */
+ public FilterTableKeyListener(JTable table, long waitToUpdateGuiMs,
+ JTextField jTextField, int... indices) {
+ this.table = table;
+ this.jTextField = jTextField;
+ this.indices = indices;
+
+ jTextField.addKeyListener(this);
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ String text = jTextField.getText();
+ newFilterForTable(
+ (TableRowSorter<AbstractTableModel>) table.getRowSorter(),
+ text, indices);
+ }
+
+ /**
+ * When a key is released, filter for the table is updated
+ */
+ private void newFilterForTable(
+ final TableRowSorter<AbstractTableModel> sorter, String text,
+ int... indices) {
+ // System.out.println("\n" + text);
+
+ String filter = "";
+ String[] split = text.trim().split("\\s");
+ for (String s : split) {
+ if (s.trim().isEmpty())
+ continue;
+ s = Pattern.quote(s);
+ s = s.substring(2, s.length() - 2);
+ filter += "|.*" + s + ".*";
+ }
+ if (filter.length() > 0)
+ filter = filter.substring(1);
+
+ // If current expression doesn't parse, don't update.
+ try {
+ // System.out.println(filter);
+ final RowFilter<AbstractTableModel, Object> rf = RowFilter
+ .regexFilter("(?i)" + filter, indices);
+ if (setRowFilterTimer != null)
+ setRowFilterTimer.cancel();
+ setRowFilterTimer = new Timer("Set rowFilter for JTable");
+ setRowFilterTimer.schedule(new TimerTask() {
+
+ @Override
+ public void run() {
+ sorter.setRowFilter(rf);
+ }
+ }, 300);
+
+ return;
+ } catch (java.util.regex.PatternSyntaxException e) {
+ return;
+ }
+
+ // sorter.setRowFilter(null);
+ }
+
+}
Property changes on: trunk/src/skrueger/swing/FilterTableKeyListener.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id URL
Name: svn:eol-style
+ native
Modified: trunk/src_junit/schmitzm/io/IOUtilTest.java
===================================================================
--- trunk/src_junit/schmitzm/io/IOUtilTest.java 2010-10-28 09:47:06 UTC (rev 1189)
+++ trunk/src_junit/schmitzm/io/IOUtilTest.java 2010-10-29 22:03:19 UTC (rev 1190)
@@ -1,6 +1,7 @@
package schmitzm.io;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
Modified: trunk/src_junit/schmitzm/swing/TestingUtil.java
===================================================================
--- trunk/src_junit/schmitzm/swing/TestingUtil.java 2010-10-28 09:47:06 UTC (rev 1189)
+++ trunk/src_junit/schmitzm/swing/TestingUtil.java 2010-10-29 22:03:19 UTC (rev 1190)
@@ -1,5 +1,7 @@
package schmitzm.swing;
+import static org.junit.Assert.assertTrue;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalExclusionType;
@@ -44,8 +46,6 @@
import schmitzm.geotools.io.GeoImportUtil;
import schmitzm.io.IOUtil;
import schmitzm.lang.LangUtil;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
/**
* Helpers to test Swing applications in general. <br/>
* If not set to @Ignore, HUDSON will complain
More information about the Schmitzm-commits
mailing list