All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.odell.glazedlists.matchers.RangeMatcherEditor Maven / Gradle / Ivy

The newest version!
/* Glazed Lists                                                 (c) 2003-2006 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.matchers;

import ca.odell.glazedlists.Filterator;

/**
 * A MatcherEditor that produces Matchers which match Objects if they lie
 * within a range of {@link Comparable}s.  This {@link RangeMatcherEditor} is
 * not coupled with any UI component that allows the user to edit the range.
 * That job is left to subclasses. This MatcherEditor is fully concrete, and
 * may be used directly by headless applications.
 *
 * 

The {@link RangeMatcherEditor} requires that either a {@link Filterator} * appropriate for extracting {@link Comparable} objects be specified in its * constructor, or that every Object to be matched is a {@link Comparable}. * * @author James Lemieux */ public class RangeMatcherEditor extends AbstractMatcherEditor { /** the filterator is used as an alternative to implementing the TextFilterable interface */ private final Filterator filterator; /** the Comparable object which starts the current range; null indicates there is no start */ private D currentRangeStart; /** the Comparable object which ends the current range; null indicates there is no end */ private D currentRangeEnd; /** * Creates a {@link RangeMatcherEditor} whose Matchers can test only elements which * are {@link Comparable} objects. * *

The {@link Matcher}s from this {@link MatcherEditor} will throw a * {@link ClassCastException} when {@link Matcher#matches} is called with * an Object that is not a {@link Comparable}. */ public RangeMatcherEditor() { this(null); } /** * Creates a {@link RangeMatcherEditor} that matches Objects using the * specified {@link Filterator} to get the {@link Comparable}s to search. * * @param filterator the object that will extract filter Comparables from * each object in the source; null indicates * the list elements are Comparables */ public RangeMatcherEditor(Filterator filterator) { this.filterator = filterator; } /** * Get the filterator used to extract Comparables from the matched elements. */ public Filterator getFilterator() { return filterator; } /** * This method is used to change the range currently matched by this * MatcherEditor. When a change to the range is detected, users of this * class are expected to call this method with the new bounds of the * range to be matched. * *

null values for either newStart or * newEnd indicate there is no start of end to the range * respectively. Consequently, calling setRange(null, null) * causes this matcher editor match all values it filters. * *

Note: if newStart and newEnd are out of * their natural order with respect to each other, their values are swapped. * For example, setRange(Jan 1, 2006, Jan 1, 1955) would swap * the values so newStart is Jan 1, 1955 and * newEnd is Jan 1, 2006. * * @param newStart the new value marking the start of the range; * null indicates there is no start * @param newEnd the new value marking the start of the range; * null indicates there is no start */ public void setRange(D newStart, D newEnd) { // swap the newStart and newEnd if they are out of order if (newStart != null && newEnd != null && newStart.compareTo(newEnd) > 0) { final D temp = newEnd; newEnd = newStart; newStart = temp; } try { // detect the special case of no range, (which matches all elements) if (newStart == null && newEnd == null) { if (currentRangeStart != null || currentRangeEnd != null) fireMatchAll(); return; } // determine if the change in the range relaxes or constrains the previous range // (if it does both, it is treated as a generic change) boolean isRelaxed = false; boolean isConstrained = false; // determine the type of change that occurred at the start of the range int newStartVsOldStart = compare(newStart, currentRangeStart, true); isRelaxed |= newStartVsOldStart < 0; isConstrained |= newStartVsOldStart > 0; // determine the type of change that occurred at the end of the range int newEndVsOldEnd = compare(newEnd, currentRangeEnd, false); isRelaxed |= newEndVsOldEnd > 0; isConstrained |= newEndVsOldEnd < 0; // construct a matcher describing the new range final Matcher matcher = Matchers.rangeMatcher(newStart, newEnd, filterator); // fire the appropriate matcher event if (isRelaxed && isConstrained) fireChanged(matcher); else if (isRelaxed) fireRelaxed(matcher); else if (isConstrained) fireConstrained(matcher); } finally { currentRangeStart = newStart; currentRangeEnd = newEnd; } } /** * Compare the specified two values, treating null as either before * all other values or after all other values. */ private static int compare(Comparable a, Comparable b, boolean nullsBeforeAll) { if(a == null && b == null) return 0; else if(a == null) return nullsBeforeAll ? -1 : 1; else if(b == null) return nullsBeforeAll ? 1 : -1; else return a.compareTo(b); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy