001: /*
002: * $Id: SortableListViewHeader.java 460265 2006-04-16 13:36:52Z jdonnerstag $
003: * $Revision: 460265 $ $Date: 2006-04-16 15:36:52 +0200 (Sun, 16 Apr 2006) $
004: *
005: * ==================================================================== Licensed
006: * under the Apache License, Version 2.0 (the "License"); you may not use this
007: * file except in compliance with the License. You may obtain a copy of the
008: * License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.examples.displaytag.list;
019:
020: import java.util.Collections;
021: import java.util.Comparator;
022:
023: import wicket.markup.ComponentTag;
024: import wicket.markup.html.border.Border;
025: import wicket.markup.html.link.Link;
026:
027: /**
028: * Sortable list view header component for a single list view column.
029: * Functionality provided includes sorting the underlying list view and changing
030: * the colours (style) of the header.
031: *
032: * @see SortableListViewHeaderGroup
033: * @see SortableListViewHeaders
034: * @author Juergen Donnerstag
035: */
036: public abstract class SortableListViewHeader extends Border {
037: /** Sort ascending or descending */
038: private boolean ascending;
039:
040: /** All sortable columns of a single list view are grouped */
041: private final SortableListViewHeaderGroup group;
042:
043: /**
044: * Construct.
045: *
046: * @param id
047: * The component's id
048: * @param group
049: * The group of headers the new one will be added to
050: */
051: public SortableListViewHeader(final String id,
052: final SortableListViewHeaderGroup group) {
053: super (id);
054:
055: // Default to descending.
056: this .ascending = false;
057: this .group = group;
058:
059: // If user clicks on the header, sorting will reverse
060: add(new Link("actionLink") {
061: public void onClick() {
062: // call SortableTableHeaders implementation
063: SortableListViewHeader.this .linkClicked();
064: }
065: });
066: }
067:
068: /**
069: * Compare two objects (list elements of list view's model object). Both
070: * objects must implement Comparable. In order to compare basic types like
071: * int or double, simply subclass the method.
072: *
073: * @param o1
074: * first object
075: * @param o2
076: * second object
077: * @return comparision result
078: */
079: protected int compareTo(Object o1, Object o2) {
080: Comparable obj1 = getObjectToCompare(o1);
081: Comparable obj2 = getObjectToCompare(o2);
082: return obj1.compareTo(obj2);
083: }
084:
085: /**
086: * Get CSS style for the header based on ascending / descending. Delegate to
087: * the header group to determine the style.
088: *
089: * @return css class
090: */
091: protected final String getCssClass() {
092: // TODO General: This needs to be integrated with our CSS design
093: return group.getCssClass(getId(), ascending);
094: }
095:
096: /**
097: * Returns the comparable object of the list view the header/column is
098: * referring to, e.g. obj.getId();
099: *
100: * @param object
101: * the ListItems model object
102: * @return The object to compare
103: */
104: protected Comparable getObjectToCompare(Object object) {
105: return (Comparable) object;
106: }
107:
108: /**
109: * Header has been clicked. Define what to do.
110: */
111: protected void linkClicked() {
112: // change sorting order: ascending <-> descending
113: ascending = !ascending;
114:
115: // Tell the header group that something has changed
116: group.setSortedColumn(getId());
117:
118: // sort the list view's model data accordingly
119: sort();
120: }
121:
122: /**
123: * Delegate to the header group to handle the tag.
124: *
125: * @see wicket.Component#onComponentTag(wicket.markup.ComponentTag)
126: * @param tag
127: * The current ComponentTag to handle
128: */
129: protected void onComponentTag(final ComponentTag tag) {
130: group.handleComponentTag(tag, getCssClass());
131: }
132:
133: /**
134: * Sort list view's model object based on column data
135: */
136: protected void sort() {
137: Collections.sort(group.getListViewModelObject(),
138: new Comparator() {
139: public int compare(Object o1, Object o2) {
140: if (ascending) {
141: return compareTo(o1, o2);
142: } else {
143: return compareTo(o2, o1);
144: }
145: }
146: });
147: }
148: }
|