package com.cedarsoft.spring.rcp.tbpanel;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
import ca.odell.glazedlists.matchers.MatcherEditor;
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
import com.cedarsoft.spring.rcp.table.ExtendedObjectTable;
import com.cedarsoft.spring.rcp.table.FinalEventListFactory;
import com.cedarsoft.spring.rcp.table.ObjectTable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.springframework.richclient.layout.TableLayoutBuilder;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Creates a filter that is based on one text field
* //Todo add support for multiple columns/rows
*
* @param <T> the type
*/
public class MultipleFieldFilterFactory<T> extends AbstractFilterFactory<T> {
@NotNull
@NonNls
protected final List<String> filteredProperties = new ArrayList<String>();
/**
* Creates a new filter factory
*
* @param filteredProperties the properties that are used to filter
*/
public MultipleFieldFilterFactory( @NonNls @NotNull String... filteredProperties ) {
this.filteredProperties.addAll( Arrays.asList( filteredProperties ) );
}
@Override
protected void fillFilterPanel( @NotNull JPanel filterPanel, @NotNull ObjectTable<T> objectTable ) {
Map<String, JTextField> filterFields = new HashMap<String, JTextField>();
TableLayoutBuilder builder = new TableLayoutBuilder( filterPanel );
for ( String filteredProperty : filteredProperties ) {
// builder.cell( getComponentFactory().createLabel( objectId + '.' + filteredProperty + KEY_SUFFIX_FILTER_LABEL ) );
builder.cell( getComponentFactory().createLabel( createMessageKeys( filteredProperty ) ) );
builder.labelGapCol();
JTextField filterField = getComponentFactory().createTextField();
// filterField.setToolTipText( getMessage(filteredProperty, KEY_LABEL, KEY_FILTER) );
builder.cell( filterField );
builder.gapCol();
filterFields.put( filteredProperty, filterField );
}
builder.getPanel();
configureFiltering( objectTable, filterFields );
}
@NotNull
@NonNls
private static String[] createMessageKeys( @NotNull @NonNls String filteredProperty ) {
return new String[]{filteredProperty + '.' + KEY_FILTER_LABEL,
filteredProperty + '.' + KEY_LABEL,
filteredProperty
};
}
public void configureFiltering( @NotNull ObjectTable<T> objectTable, @NotNull final Map<String, JTextField> filterFields ) {
// Construct and install our filtering list. This filter will allow the user
// to simply type data into the txtFilter (JTextField). With the configuration
// setup below, the text entered by the user will be matched against the values
// in the lastName and address.address1 properties of the contacts in the table.
// The GlazedLists filtered lists is used to accomplish this.
objectTable.setFinalEventListFactory( new FinalEventListFactory<T>() {
@NotNull
@Override
public EventList<T> create( @NotNull SortedList<T> baseEventList ) {
EventList<MatcherEditor<T>> matchers = GlazedLists.eventListOf();
for ( Map.Entry<String, JTextField> entry : filterFields.entrySet() ) {
String property = entry.getKey();
JTextField textField = entry.getValue();
TextFilterator<T> filterator = GlazedLists.<T>textFilterator( property );
matchers.add( new TextComponentMatcherEditor<T>( textField, filterator ) );
}
return new FilterList<T>( baseEventList, new CompositeMatcherEditor<T>( matchers ) );
}
} );
}
}