From 161e73be6772508e0b15c8a3649324c78c2c45fd Mon Sep 17 00:00:00 2001 From: fmittag Date: Tue, 21 Aug 2012 14:18:14 +0200 Subject: [PATCH] Final cleanup of preferred sorting order for race columns (bug 25, 917) --- .../sap/sailing/domain/common/DetailType.java | 2 +- .../domain/common/InvertibleComparator.java | 26 ++ .../sailing/domain/common/SortingOrder.java | 10 +- .../impl/InvertibleComparatorAdapter.java | 56 +++++ .../gwt/ui/test/LeaderboardPanelMock.java | 4 +- .../FormattedDoubleLegDetailColumn.java | 5 +- .../gwt/ui/leaderboard/LeaderboardPanel.java | 143 ++++------- .../sailing/gwt/ui/leaderboard/LegColumn.java | 42 ++-- .../gwt/ui/leaderboard/LegDetailColumn.java | 16 +- .../leaderboard/ManeuverCountRaceColumn.java | 20 +- .../gwt/ui/leaderboard/RankGainColumn.java | 6 +- .../gwt/ui/leaderboard/SortableColumn.java | 33 +-- .../gwt/ui/leaderboard/SortedCellTable.java | 228 ++++++++++++++++++ ...> SortedCellTableWithStylableHeaders.java} | 135 +++++------ 14 files changed, 471 insertions(+), 255 deletions(-) create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/InvertibleComparator.java create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/InvertibleComparatorAdapter.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTable.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/{CellTableWithStylableHeaders.java => SortedCellTableWithStylableHeaders.java} (89%) mode change 100755 => 100644 diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java index 4adc0595a6d..d9fe674edb0 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java @@ -12,7 +12,7 @@ import static com.sap.sailing.domain.common.SortingOrder.*; * */ public enum DetailType implements Serializable { - DISTANCE_TRAVELED(0, DESCENDING), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), + DISTANCE_TRAVELED(0, ASCENDING), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), RANK_GAIN(0, DESCENDING), NUMBER_OF_MANEUVERS(0, ASCENDING), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING), GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), WINDWARD_DISTANCE_TO_GO_IN_METERS(0, ASCENDING), diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/InvertibleComparator.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/InvertibleComparator.java new file mode 100644 index 00000000000..d2779ad9b9f --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/InvertibleComparator.java @@ -0,0 +1,26 @@ +package com.sap.sailing.domain.common; + +import java.util.Comparator; + +/** + * An invertible comparator with an "ascending" flag denoting whether comparison results should be treated in + * forward (standard ascending) order or flipped for reverse (descending) order. + */ +public interface InvertibleComparator extends Comparator { + + /** + * Specify the sort order: ascending (true) or descending (false). + */ + public void setAscending(boolean ascending); + + /** + * Return the sort order: ascending (true) or descending (false). + */ + public boolean isAscending(); + + /** + * Invert the sort order + * Ascending -> descending or descending -> ascending. + */ + public void invertOrder(); +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/SortingOrder.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/SortingOrder.java index 7b47e1c1ec5..13fb708e5c4 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/SortingOrder.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/SortingOrder.java @@ -1,5 +1,13 @@ package com.sap.sailing.domain.common; public enum SortingOrder { - NONE, ASCENDING, DESCENDING; + NONE, ASCENDING, DESCENDING; + + public boolean isAscending() { + return this == ASCENDING; + } + + public boolean isDescending() { + return this == DESCENDING; + } } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/InvertibleComparatorAdapter.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/InvertibleComparatorAdapter.java new file mode 100644 index 00000000000..77ce785363f --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/InvertibleComparatorAdapter.java @@ -0,0 +1,56 @@ +package com.sap.sailing.domain.common.impl; + +import com.sap.sailing.domain.common.InvertibleComparator; + +/** + * An adapter for an invertible comparator. + */ +public class InvertibleComparatorAdapter implements InvertibleComparator { + boolean ascending; + + /** + * Create an InvertibleComparator that sorts ascending by default. + */ + public InvertibleComparatorAdapter() { + this(true); + } + + /** + * Create an InvertibleComparator that sorts based on the provided order. + * @param ascending + * the sort order: ascending (true) or descending (false) + */ + public InvertibleComparatorAdapter(boolean ascending) { + setAscending(ascending); + } + + /** + * Specify the sort order: ascending (true) or descending (false). + */ + public void setAscending(boolean ascending) { + this.ascending = ascending; + } + + /** + * Return the sort order: ascending (true) or descending (false). + */ + public boolean isAscending() { + return this.ascending; + } + + /** + * Invert the sort order Ascending -> descending or descending -> ascending. + */ + public void invertOrder() { + this.ascending = !this.ascending; + } + + public int compare(T o1, T o2) { + throw new RuntimeException("You muste overwrite the compare() method to use this comparator "); + } + + @Override + public String toString() { + return "InvertibleComparatorAdpapter: ascending=" + this.ascending; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/LeaderboardPanelMock.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/LeaderboardPanelMock.java index 52fd79cb7d2..65e3e9f893b 100644 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/LeaderboardPanelMock.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/LeaderboardPanelMock.java @@ -1,6 +1,5 @@ package com.sap.sailing.gwt.ui.test; -import com.google.gwt.user.cellview.client.CellTable; import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; @@ -8,6 +7,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory; import com.sap.sailing.gwt.ui.leaderboard.SortableColumn; +import com.sap.sailing.gwt.ui.leaderboard.SortedCellTable; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; import com.sap.sailing.gwt.ui.shared.RaceColumnDTO; @@ -47,7 +47,7 @@ public class LeaderboardPanelMock extends LeaderboardPanel { } @Override - public CellTable getLeaderboardTable() { + public SortedCellTable getLeaderboardTable() { // TODO Auto-generated method stub return super.getLeaderboardTable(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/FormattedDoubleLegDetailColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/FormattedDoubleLegDetailColumn.java index a9963ad3b90..dfb150ec2ed 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/FormattedDoubleLegDetailColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/FormattedDoubleLegDetailColumn.java @@ -4,7 +4,6 @@ import com.google.gwt.cell.client.Cell.Context; import com.google.gwt.cell.client.TextCell; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.CellTable; import com.sap.sailing.domain.common.SortingOrder; import com.sap.sailing.gwt.ui.client.NumberFormatterFactory; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; @@ -16,8 +15,8 @@ public class FormattedDoubleLegDetailColumn extends LegDetailColumn field, int decimals, SortingOrder preferredSortingOrder, - CellTable leaderboardTable, String headerStyle, String columnStyle) { - super(title, unit, field, new TextCell(), preferredSortingOrder, leaderboardTable, headerStyle, columnStyle); + String headerStyle, String columnStyle) { + super(title, unit, field, new TextCell(), preferredSortingOrder, headerStyle, columnStyle); formatter = NumberFormatterFactory.getDecimalFormat(decimals); this.minMaxRenderer = new MinMaxRenderer(this, getComparator()); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java index fff84677c96..097fa79f411 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java @@ -3,7 +3,6 @@ package com.sap.sailing.gwt.ui.leaderboard; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -24,10 +23,7 @@ import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; -import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; -import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo; import com.google.gwt.user.cellview.client.Header; import com.google.gwt.user.cellview.client.TextHeader; import com.google.gwt.user.client.Window; @@ -50,10 +46,12 @@ import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.google.gwt.view.client.SelectionModel; import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.InvertibleComparator; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.SortingOrder; +import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor; import com.sap.sailing.gwt.ui.actions.GetLeaderboardByNameAction; @@ -115,14 +113,10 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta private final StringMessages stringMessages; - private final CellTable leaderboardTable; + private final SortedCellTable leaderboardTable; private final SelectionModel leaderboardSelectionModel; - private ListDataProvider data; - - private final ListHandler listHandler; - private LeaderboardDTO leaderboard; private final RankColumn rankColumn; @@ -347,23 +341,23 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta if (newSettings.getNameOfRaceToSort() != null) { final RaceColumn raceColumnByRaceName = getRaceColumnByRaceName(newSettings.getNameOfRaceToSort()); if (raceColumnByRaceName != null) { - sort(raceColumnByRaceName, /* ascending */ true); + getLeaderboardTable().sortColumn(raceColumnByRaceName, /* ascending */ true); } } } protected class CompetitorColumn extends SortableColumn { protected CompetitorColumn() { - super(new TextCell()); + super(new TextCell(), SortingOrder.ASCENDING); } protected CompetitorColumn(EditTextCell editTextCell) { - super(editTextCell); + super(editTextCell, SortingOrder.ASCENDING); } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { return Collator.getInstance().compare(getLeaderboard().getDisplayName(o1.competitor), @@ -406,12 +400,12 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta private class SailIDColumn extends SortableColumn { protected SailIDColumn() { - super(new TextCell()); + super(new TextCell(), SortingOrder.ASCENDING); } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { return o1.competitor.sailID == null ? o2.competitor.sailID == null ? 0 : -1 @@ -535,16 +529,15 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { List competitorsFromBestToWorst = getLeaderboard().getCompetitorsFromBestToWorst(race); - boolean ascending = isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable()); int o1Rank = competitorsFromBestToWorst.indexOf(o1.competitor) + 1; int o2Rank = competitorsFromBestToWorst.indexOf(o2.competitor) + 1; return o1Rank == 0 ? o2Rank == 0 ? 0 - : ascending ? 1 : -1 : o2Rank == 0 ? ascending ? -1 : 1 + : isAscending() ? 1 : -1 : o2Rank == 0 ? isAscending() ? -1 : 1 : o1Rank - o2Rank; } }; @@ -562,7 +555,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta /* iconURL */race.isMedalRace() ? "/gwt/images/medal_small.png" : null, LeaderboardPanel.this, this, stringMessages); return header; } - } public static DetailType[] getAvailableRaceDetailColumnTypes() { @@ -624,29 +616,29 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta result.put(DetailType.RACE_DISTANCE_TRAVELED, new FormattedDoubleLegDetailColumn(stringMessages.distanceInMeters(), "["+stringMessages .distanceInMetersUnit()+"]", new RaceDistanceTraveledInMeters(), 0, - DetailType.RACE_DISTANCE_TRAVELED.getDefaultSortingOrder(), getLeaderboardPanel() - .getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + DetailType.RACE_DISTANCE_TRAVELED.getDefaultSortingOrder(), + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); result.put(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new FormattedDoubleLegDetailColumn( stringMessages.averageSpeedInKnots(), "["+stringMessages.averageSpeedInKnotsUnit()+"]", new RaceAverageSpeedInKnots(), 2, DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); result.put(DetailType.RACE_GAP_TO_LEADER_IN_SECONDS, new FormattedDoubleLegDetailColumn(stringMessages.gapToLeaderInSeconds(), "["+stringMessages .gapToLeaderInSecondsUnit()+"]", new RaceGapToLeaderInSeconds(), 0, DetailType.RACE_GAP_TO_LEADER_IN_SECONDS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); result.put(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS, new FormattedDoubleLegDetailColumn(stringMessages.windwardDistanceToLeader(), "["+stringMessages .distanceInMetersUnit()+"]", new RaceDistanceToLeaderInMeters(), 0, DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); result.put(DetailType.RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS, new FormattedDoubleLegDetailColumn(stringMessages.averageCrossTrackErrorInMeters(), "["+stringMessages .metersUnit()+"]", new RaceAverageCrossTrackErrorInMeters(), 0, DetailType.RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); result.put(DetailType.NUMBER_OF_MANEUVERS, getManeuverCountRaceColumn()); result.put(DetailType.CURRENT_LEG, new FormattedDoubleLegDetailColumn(stringMessages.currentLeg(), "", new CurrentLeg(), 0, DetailType.CURRENT_LEG.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE)); return result; } @@ -850,7 +842,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta private final String columnStyle; protected TotalsColumn(String columnStyle) { - super(new TextCell()); + super(new TextCell(), SortingOrder.ASCENDING); this.columnStyle = columnStyle; setHorizontalAlignment(ALIGN_CENTER); } @@ -869,8 +861,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { return getLeaderboard().competitors.indexOf(o1.competitor) - getLeaderboard().competitors.indexOf(o2.competitor); @@ -891,12 +883,12 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta protected class CarryColumn extends SortableColumn { public CarryColumn() { - super(new TextCell()); + super(new TextCell(), SortingOrder.ASCENDING); setSortable(true); } protected CarryColumn(EditTextCell editTextCell) { - super(editTextCell); + super(editTextCell, SortingOrder.ASCENDING); setSortable(true); } @@ -906,8 +898,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { Double o1CarriedPoints = o1.carriedPoints; @@ -931,7 +923,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta private class RankColumn extends SortableColumn { public RankColumn() { - super(new TextCell()); + super(new TextCell(), SortingOrder.ASCENDING); setHorizontalAlignment(ALIGN_CENTER); setSortable(true); } @@ -943,8 +935,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter() { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { final int rank1 = getLeaderboard().getRank(o1.competitor); @@ -1012,7 +1004,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta LEG_COLUMN_STYLE = tableResources.cellTableStyle().cellTableLegColumn(); LEG_DETAIL_COLUMN_STYLE = tableResources.cellTableStyle().cellTableLegDetailColumn(); TOTAL_COLUMN_STYLE = tableResources.cellTableStyle().cellTableTotalColumn(); - leaderboardTable = new CellTableWithStylableHeaders( + leaderboardTable = new SortedCellTableWithStylableHeaders( /* pageSize */10000, tableResources); getLeaderboardTable().setWidth("100%"); if (userAgent.isMobile() == UserAgentDetails.PlatformTypes.MOBILE) { @@ -1031,11 +1023,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta /* listenersNotToNotify */LeaderboardPanel.this); } }); - getLeaderboardTable().setSelectionModel(leaderboardSelectionModel); - setData(new ListDataProvider()); - getData().addDataDisplay(getLeaderboardTable()); - listHandler = new ListHandler(getData().getList()); - getLeaderboardTable().addColumnSortHandler(listHandler); + leaderboardTable.setSelectionModel(leaderboardSelectionModel); loadCompleteLeaderboard(getLeaderboardDisplayDate()); if (this.preSelectedRace == null) { @@ -1208,8 +1196,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta * the column style according to the {@link SortableColumn#getColumnStyle() column's style definition}. */ protected void addColumn(SortableColumn column) { - getLeaderboardTable().addColumn(column, column.getHeader()); - listHandler.setComparator(column, column.getComparator()); + leaderboardTable.addColumn(column, column.getHeader(), column.getComparator(), column.getPreferredSortingOrder().isAscending()); String columnStyle = column.getColumnStyle(); if (columnStyle != null) { getLeaderboardTable().addColumnStyleName(getLeaderboardTable().getColumnCount() - 1, columnStyle); @@ -1220,9 +1207,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta // remove column styles of those columns whose index will shift right by // one: removeColumnStyles(beforeIndex); - getLeaderboardTable().insertColumn(beforeIndex, column, column.getHeader()); + getLeaderboardTable().insertColumn(beforeIndex, column, column.getHeader(), column.getComparator(), column.getPreferredSortingOrder().isAscending()); addColumnStyles(beforeIndex); - listHandler.setComparator(column, column.getComparator()); } private void addColumnStyles(int startColumn) { @@ -1352,21 +1338,15 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } } } - Comparator comparator = getComparatorForSelectedSorting(); - if (comparator != null) { - Collections.sort(getData().getList(), comparator); + if (leaderboardTable.getCurrentlySortedColumn() != null) { + leaderboardTable.sort(); } else { SortableColumn columnToSortFor = getDefaultSortColumn(); - // if no sorting was selected, sort by the preferred sorting order of the sort column - boolean ascending = true; - if(columnToSortFor.getPreferredSortingOrder() == SortingOrder.DESCENDING) { - ascending = false; - } - sort(columnToSortFor, ascending); + leaderboardTable.sortColumn(columnToSortFor, columnToSortFor.getPreferredSortingOrder().isAscending()); } // Reselect the selected rows clearSelection(); - for (LeaderboardRowDTO row : data.getList()) { + for (LeaderboardRowDTO row : getLeaderboardTable().getDataProvider().getList()) { if (competitorSelectionProvider.isSelected(row.competitor)) { leaderboardSelectionModel.setSelected(row, true); } @@ -1488,19 +1468,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta return defaultSortColumn; } - /** - * Sorts the leaderboard contents in ascending order according to columnToSortFor's comparator and - * marks the table's column sort list so. - */ - private void sort(SortableColumn columnToSortFor, boolean ascending) { - Collections.sort(getData().getList(), getComparator(columnToSortFor, ascending)); - ColumnSortInfo columnSortInfo = getLeaderboardTable().getColumnSortList().push(columnToSortFor); - if (ascending != columnSortInfo.isAscending()) { - // flip ascending bit by repeating the push: - getLeaderboardTable().getColumnSortList().push(columnToSortFor); - } - } - private void clearSelection() { for (LeaderboardRowDTO row : getData().getList()) { leaderboardSelectionModel.setSelected(row, false); @@ -1525,30 +1492,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta return columnsToAddImplicitly; } - private Comparator getComparatorForSelectedSorting() { - Comparator result = null; - if (getLeaderboardTable().getColumnSortList().size() > 0) { - ColumnSortInfo columnSortInfo = getLeaderboardTable().getColumnSortList().get(0); - @SuppressWarnings("unchecked") - SortableColumn castResult = (SortableColumn) columnSortInfo - .getColumn(); - final boolean ascending = columnSortInfo.isAscending(); - result = getComparator(castResult, ascending); - } - return result; - } - - private Comparator getComparator(SortableColumn column, - final boolean ascending) { - Comparator result; - if (ascending) { - result = column.getComparator(); - } else { - result = Collections.reverseOrder(column.getComparator()); - } - return result; - } - private RankColumn getRankColumn() { return rankColumn; } @@ -1857,7 +1800,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta return new CarryColumn(); } - protected CellTable getLeaderboardTable() { + protected SortedCellTable getLeaderboardTable() { return leaderboardTable; } @@ -1878,11 +1821,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta } protected ListDataProvider getData() { - return data; - } - - private void setData(ListDataProvider data) { - this.data = data; + return getLeaderboardTable().getDataProvider(); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java index f565ac38d9f..0096010adb1 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java @@ -1,16 +1,16 @@ package com.sap.sailing.gwt.ui.leaderboard; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.gwt.cell.client.TextCell; import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Header; import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.InvertibleComparator; import com.sap.sailing.domain.common.SortingOrder; +import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.leaderboard.LegDetailColumn.LegDetailField; import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO; @@ -122,10 +122,9 @@ public class LegColumn extends ExpandableSortableColumn { } private class ManeuverCountLegDetailsColumn extends FormattedDoubleLegDetailColumn { - public ManeuverCountLegDetailsColumn(String title, CellTable leaderboardTable, - String headerStyle, String columnStyle) { + public ManeuverCountLegDetailsColumn(String title, String headerStyle, String columnStyle) { super(title, /*unit*/null, /* field */ null, /* decimals */ 0, DetailType.NUMBER_OF_MANEUVERS.getDefaultSortingOrder(), - leaderboardTable, headerStyle, columnStyle); + headerStyle, columnStyle); } @Override @@ -235,41 +234,39 @@ public class LegColumn extends ExpandableSortableColumn { Map> result = new HashMap>(); result.put(DetailType.DISTANCE_TRAVELED, new FormattedDoubleLegDetailColumn(stringConstants.distanceInMeters(), "["+stringConstants.distanceInMetersUnit()+"]", - new DistanceTraveledInMeters(), 0, DetailType.DISTANCE_TRAVELED.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + new DistanceTraveledInMeters(), 0, DetailType.DISTANCE_TRAVELED.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new FormattedDoubleLegDetailColumn( stringConstants.averageSpeedInKnots(), "["+stringConstants.averageSpeedInKnotsUnit()+"]", new AverageSpeedOverGroundInKnots(), 2, - DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS.getDefaultSortingOrder(), leaderboardPanel - .getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS, new FormattedDoubleLegDetailColumn( stringConstants.currentSpeedOverGroundInKnots(), "["+stringConstants.currentSpeedOverGroundInKnotsUnit()+"]", new CurrentSpeedOverGroundInKnots(), - 2, DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + 2, DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS, new FormattedDoubleLegDetailColumn(stringConstants.estimatedTimeToNextWaypointInSeconds(), "["+stringConstants.estimatedTimeToNextWaypointInSecondsUnit()+"]", new EstimatedTimeToNextWaypointInSeconds(), 1, DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + detailHeaderStyle, detailColumnStyle)); result.put(DetailType.GAP_TO_LEADER_IN_SECONDS, new FormattedDoubleLegDetailColumn(stringConstants.gapToLeaderInSeconds(), "["+stringConstants.gapToLeaderInSecondsUnit()+"]", new GapToLeaderInSeconds(), 0, DetailType.GAP_TO_LEADER_IN_SECONDS.getDefaultSortingOrder(), - getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + detailHeaderStyle, detailColumnStyle)); result.put(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, new FormattedDoubleLegDetailColumn(stringConstants.velocityMadeGoodInKnots(), "["+stringConstants.velocityMadeGoodInKnotsUnit()+"]", new VelocityMadeGoodInKnots(), 2, - DetailType.VELOCITY_MADE_GOOD_IN_KNOTS.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + DetailType.VELOCITY_MADE_GOOD_IN_KNOTS.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS, new FormattedDoubleLegDetailColumn( stringConstants.windwardDistanceToGoInMeters(), "["+stringConstants.windwardDistanceToGoInMetersUnit()+"]", new WindwardDistanceToGoInMeters(), - 0, DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + 0, DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.RANK_GAIN, new RankGainColumn(stringConstants.rankGain(), new RankGain(), - getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + detailHeaderStyle, detailColumnStyle)); result.put(DetailType.NUMBER_OF_MANEUVERS, new ManeuverCountLegDetailsColumn( - stringConstants.numberOfManeuvers(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + stringConstants.numberOfManeuvers(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.TIME_TRAVELED, new FormattedDoubleLegDetailColumn(stringConstants.time(), "[" + stringConstants.secondsUnit() + "]", new TimeTraveledInSeconds(), 0, - DetailType.TIME_TRAVELED.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), - detailHeaderStyle, detailColumnStyle)); + DetailType.TIME_TRAVELED.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.AVERAGE_CROSS_TRACK_ERROR_IN_METERS, new FormattedDoubleLegDetailColumn(stringConstants.averageCrossTrackErrorInMeters(), "[" + stringConstants.metersUnit() + "]", new AverageCrossTrackErrorInMeters(), 0, - DetailType.AVERAGE_CROSS_TRACK_ERROR_IN_METERS.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), + DetailType.AVERAGE_CROSS_TRACK_ERROR_IN_METERS.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); return result; } @@ -307,15 +304,14 @@ public class LegColumn extends ExpandableSortableColumn { } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter(getPreferredSortingOrder().isAscending()) { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { - boolean ascending = isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable()); LegEntryDTO o1Entry = getLegEntry(o1); LegEntryDTO o2Entry = getLegEntry(o2); - return o1Entry == null ? o2Entry == null ? 0 : ascending?1:-1 - : o2Entry == null ? ascending?-1:1 : o1Entry.rank - o2Entry.rank; + return o1Entry == null ? o2Entry == null ? 0 : isAscending()?1:-1 + : o2Entry == null ? isAscending()?-1:1 : o1Entry.rank - o2Entry.rank; } }; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegDetailColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegDetailColumn.java index fa28ebd6392..272d8c4c433 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegDetailColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegDetailColumn.java @@ -1,20 +1,18 @@ package com.sap.sailing.gwt.ui.leaderboard; -import java.util.Comparator; - import com.google.gwt.cell.client.Cell; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Header; import com.google.gwt.user.cellview.client.SafeHtmlHeader; +import com.sap.sailing.domain.common.InvertibleComparator; import com.sap.sailing.domain.common.SortingOrder; +import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter; import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; public abstract class LegDetailColumn, RenderingType> extends SortableColumn { private final String title; private final LegDetailField field; - private final CellTable leaderboardTable; private final String headerStyle; private final String columnStyle; private final String unit; @@ -24,13 +22,12 @@ public abstract class LegDetailColumn, Rendering } protected LegDetailColumn(String title, String unit, LegDetailField field, Cell cell, - SortingOrder preferredSortingOrder, CellTable leaderboardTable, String headerStyle, String columnStyle) { + SortingOrder preferredSortingOrder, String headerStyle, String columnStyle) { super(cell, preferredSortingOrder); setHorizontalAlignment(ALIGN_CENTER); this.title = title; this.unit = unit; this.field = field; - this.leaderboardTable = leaderboardTable; this.headerStyle = headerStyle; this.columnStyle = columnStyle; } @@ -54,16 +51,15 @@ public abstract class LegDetailColumn, Rendering } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter(getPreferredSortingOrder().isAscending()) { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { - boolean ascending = isSortedAscendingForThisColumn(leaderboardTable); try { @SuppressWarnings("unchecked") Comparable value1 = (Comparable) getFieldValue(o1); FieldType value2 = getFieldValue(o2); - return value1 == null ? value2 == null ? 0 : ascending ? 1 : -1 : value2 == null ? ascending ? -1 + return value1 == null ? value2 == null ? 0 : isAscending() ? 1 : -1 : value2 == null ? isAscending() ? -1 : 1 : value1.compareTo(value2); } catch (Exception e) { throw new RuntimeException(e); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ManeuverCountRaceColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ManeuverCountRaceColumn.java index 5094c97675f..bd0bdafcd25 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ManeuverCountRaceColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ManeuverCountRaceColumn.java @@ -1,6 +1,5 @@ package com.sap.sailing.gwt.ui.leaderboard; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -10,14 +9,16 @@ import com.google.gwt.cell.client.TextCell; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.cellview.client.Header; +import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.InvertibleComparator; +import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter; +import com.sap.sailing.domain.common.impl.Util.Triple; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.leaderboard.LegDetailColumn.LegDetailField; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; import com.sap.sailing.gwt.ui.shared.LegEntryDTO; -import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.impl.Util.Triple; public class ManeuverCountRaceColumn extends ExpandableSortableColumn implements HasStringAndDoubleValue { @@ -182,14 +183,13 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn im } @Override - public Comparator getComparator() { - return new Comparator() { + public InvertibleComparator getComparator() { + return new InvertibleComparatorAdapter(getPreferredSortingOrder().isAscending()) { @Override public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) { - boolean ascending = isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable()); Double val1 = getDoubleValue(o1); Double val2 = getDoubleValue(o2); - return val1 == null ? val2 == null ? 0 : ascending ? 1 : -1 : val2 == null ? ascending ? -1 : 1 : val1 + return val1 == null ? val2 == null ? 0 : isAscending() ? 1 : -1 : val2 == null ? isAscending() ? -1 : 1 : val1 .compareTo(val2); } }; @@ -258,11 +258,11 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn im String detailColumnStyle) { Map> result = new HashMap>(); result.put(DetailType.TACK, new FormattedDoubleLegDetailColumn(stringConstants.tack(), "", new NumberOfTacks(), - 0, DetailType.TACK.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + 0, DetailType.TACK.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.JIBE, new FormattedDoubleLegDetailColumn(stringConstants.jibe(), "", new NumberOfJibes(), - 0, DetailType.JIBE.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle)); + 0, DetailType.JIBE.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); result.put(DetailType.PENALTY_CIRCLE, new FormattedDoubleLegDetailColumn(stringConstants.penaltyCircle(), "", - new NumberOfPenaltyCircles(), 0, DetailType.PENALTY_CIRCLE.getDefaultSortingOrder(), getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, + new NumberOfPenaltyCircles(), 0, DetailType.PENALTY_CIRCLE.getDefaultSortingOrder(), detailHeaderStyle, detailColumnStyle)); return result; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/RankGainColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/RankGainColumn.java index cb4deb46c5c..393a1218683 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/RankGainColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/RankGainColumn.java @@ -5,7 +5,6 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.text.shared.SafeHtmlRenderer; -import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.client.ui.ImageResourceRenderer; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; @@ -13,9 +12,8 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; public class RankGainColumn extends LegDetailColumn { private static final LeaderboardResources leaderboardResources = GWT.create(LeaderboardResources.class); - public RankGainColumn(String title, LegDetailField field, CellTable leaderboardTable, - String headerStyle, String columnStyle) { - super(title, null, field, new RankGainCell(), DetailType.RANK_GAIN.getDefaultSortingOrder(), leaderboardTable, headerStyle, columnStyle); + public RankGainColumn(String title, LegDetailField field, String headerStyle, String columnStyle) { + super(title, null, field, new RankGainCell(), DetailType.RANK_GAIN.getDefaultSortingOrder(), headerStyle, columnStyle); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortableColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortableColumn.java index c152de27b46..090a8759ae6 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortableColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortableColumn.java @@ -1,25 +1,15 @@ package com.sap.sailing.gwt.ui.leaderboard; -import java.util.Comparator; - import com.google.gwt.cell.client.Cell; -import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; -import com.google.gwt.user.cellview.client.ColumnSortList; import com.google.gwt.user.cellview.client.Header; +import com.sap.sailing.domain.common.InvertibleComparator; import com.sap.sailing.domain.common.SortingOrder; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO; public abstract class SortableColumn extends Column { private SortingOrder preferredSortingOrder; - protected SortableColumn(Cell cell) { - super(cell); - setSortable(true); - this.preferredSortingOrder = SortingOrder.NONE; - } - protected SortableColumn(Cell cell, SortingOrder preferredSortingOrder) { super(cell); setSortable(true); @@ -28,26 +18,7 @@ public abstract class SortableColumn extends Column { protected void updateMinMax(LeaderboardDTO leaderboard) {} - /** - * To enable sorting of null values to the end even in ascending order, the comparators provided - * by the subclasses will want to know whether the leaderboard table is currently sorted in ascending order - * for this column. - */ - protected boolean isSortedAscendingForThisColumn(CellTable leaderboardTable) { - boolean result = true; - ColumnSortList sortList = leaderboardTable.getColumnSortList(); - SortingOrder sortingOrder = preferredSortingOrder; - if(sortList.size() > 0 && sortList.get(0).getColumn() == this) { - sortingOrder = sortList.get(0).isAscending() ? SortingOrder.ASCENDING : SortingOrder.DESCENDING; - } - - if(sortingOrder == SortingOrder.DESCENDING) - result = false; - - return result; - } - - public abstract Comparator getComparator(); + public abstract InvertibleComparator getComparator(); public abstract Header getHeader(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTable.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTable.java new file mode 100644 index 00000000000..89ca882997e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTable.java @@ -0,0 +1,228 @@ +package com.sap.sailing.gwt.ui.leaderboard; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.Column; +import com.google.gwt.user.cellview.client.ColumnSortEvent; +import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; +import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo; +import com.google.gwt.user.cellview.client.Header; +import com.google.gwt.view.client.ListDataProvider; +import com.sap.sailing.domain.common.InvertibleComparator; + +public class SortedCellTable extends CellTable { + + /** + * The currently sorted column + */ + private Column currentlySortedColumn; + + /** + * The default sort orders of all columns + */ + private Map, Boolean> defaultSortOrderMap = new HashMap, Boolean>(); + + /** + * Comparators associated with their columns + */ + private Map, InvertibleComparator> comparators = new HashMap, InvertibleComparator>(); + + /** + * Column to sort when the data provider's list is refreshed using {@link SortedCellTable#setList(List)} + */ + private Column initialSortColumn; + + /** + * The data provider for the celltable + */ + private ListDataProvider dataProvider; + + /** + * Column sorting handler to control the sorting + */ + private ListHandler columnSortHandler; + + public SortedCellTable(int pageSize, LeaderboardTableResources resources) { + super(pageSize, resources); + dataProvider = new ListDataProvider(); + dataProvider.addDataDisplay(this); + columnSortHandler = new ListHandler(dataProvider.getList()) { + + @Override + public void onColumnSort(ColumnSortEvent event) { + @SuppressWarnings("unchecked") + Column column = (Column) event.getColumn(); + if (column == null) { + return; + } + + final InvertibleComparator comparator = comparators.get(column); + if (comparator == null) { + return; + } + + boolean ascending; + if (column.equals(currentlySortedColumn)) { + comparator.invertOrder(); + ascending = comparator.isAscending(); + } else { + // Initial sort; look up which direction we need + ascending = defaultSortOrderMap.get(column); + comparator.setAscending(ascending); + } + + sortColumn(column, comparator, ascending); + } + + @Override + public void setComparator(Column column, Comparator comparator) { + comparators.put(column, (InvertibleComparator) comparator); + super.setComparator(column, comparator); + } + + }; + addColumnSortHandler(columnSortHandler); + } + + public Column getCurrentlySortedColumn() { + return currentlySortedColumn; + } + + public void sort() { + if(currentlySortedColumn != null) { + InvertibleComparator comparator = comparators.get(currentlySortedColumn); + if (comparator != null) { + sortColumn(currentlySortedColumn, comparator, comparator.isAscending()); + } + } + } + + public void sortColumn(Column column, boolean ascending) { + InvertibleComparator comparator = comparators.get(column); + if (comparator != null) { + sortColumn(column, comparator, ascending); + } + } + + private void sortColumn(Column column, Comparator comparator, boolean ascending) { + if(ascending) { + Collections.sort(dataProvider.getList(), comparator); + } else { + Collections.sort(dataProvider.getList(), Collections.reverseOrder(comparator)); + } + getColumnSortList().push(new ColumnSortInfo(column, ascending)); + currentlySortedColumn = column; + } + + /** + * Adds a column to the table and sets its sortable state + * + * @param column + * @param headerName + * @param sortable + */ + public void addColumn(Column column, String headerName, InvertibleComparator comparator, boolean ascendingSorting) { + addColumn(column, headerName); + column.setSortable(comparator != null); + if (comparator != null) { + defaultSortOrderMap.put(column, ascendingSorting); + comparators.put(column, comparator); + } + } + + /** + * Adds a column to the table and sets its sortable state + * + * @param column + * @param header + * @param sortable + */ + public void addColumn(Column column, Header header, InvertibleComparator comparator, boolean ascendingSorting) { + addColumn(column, header); + column.setSortable(comparator != null); + if (comparator != null) { + defaultSortOrderMap.put(column, ascendingSorting); + comparators.put(column, comparator); + } + } + + public void insertColumn(int beforeIndex, Column column, Header header, InvertibleComparator comparator, boolean ascendingSorting) { + insertColumn(beforeIndex, column, header); + column.setSortable(comparator != null); + if (comparator != null) { + defaultSortOrderMap.put(column, ascendingSorting); + comparators.put(column, comparator); + } + } + + /** + * Sets the column to sort when the data list is reset using {@link SortedCellTable#setList(List)} + * + * @param column + */ + public void setInitialSortColumn(Column column) { + initialSortColumn = column; + } + + /** + * Sets a comparator to use when sorting the given column + * + * @param column + * @param comparator + */ + public void setComparator(Column column, InvertibleComparator comparator) { + columnSortHandler.setComparator(column, comparator); + } + + /** + * Sets the sort order to use when this column is clicked and it was not previously sorted + * + * @param column + * @param ascending + */ + public void setDefaultSortOrder(Column column, boolean ascending) { + defaultSortOrderMap.put(column, ascending); + } + + /** + * Sets the table's data provider list and sorts the table based on the column given in + * {@link SortedCellTable#setInitialSortColumn(Column)} + * + * @param list + */ + public void setList(List list) { + dataProvider.getList().clear(); + if (list != null) { + for (T element : list) { + dataProvider.getList().add(element); + } + } + + // Do a first-time sort based on which column was set in + // setInitialSortColumn() + if (initialSortColumn != null) { + Collections.sort(dataProvider.getList(), new Comparator() { + + @Override + public int compare(T o1, T o2) { + return (defaultSortOrderMap.get(initialSortColumn) ? 1 : -1) + * comparators.get(initialSortColumn).compare(o1, o2); + } + + }); + // Might as well get the little arrow on the header to make it + // official + getColumnSortList().push(new ColumnSortInfo(initialSortColumn, defaultSortOrderMap.get(initialSortColumn))); + currentlySortedColumn = initialSortColumn; + } + } + + public ListDataProvider getDataProvider() { + return dataProvider; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CellTableWithStylableHeaders.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTableWithStylableHeaders.java old mode 100755 new mode 100644 similarity index 89% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CellTableWithStylableHeaders.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTableWithStylableHeaders.java index bdd558e5e89..682596814cb --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CellTableWithStylableHeaders.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/SortedCellTableWithStylableHeaders.java @@ -1,68 +1,67 @@ -package com.sap.sailing.gwt.ui.leaderboard; - -import java.util.List; - -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.core.client.Scheduler.ScheduledCommand; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.Node; -import com.google.gwt.dom.client.NodeList; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.view.client.SelectionModel; - -/** - * Uses {@link SortableColumn#getHeaderStyle()} to optionally add a custom CSS style to the <th> table - * header cell for the respective column.

- * - * The implementation works by overriding {@link #renderRowValues(SafeHtmlBuilder, List, int, SelectionModel)} which - * first calls the super implementation which is expected to render the header cells already into the implementation - * {@link Element}, then uses {@link #updateColumnHeaderStyles()} to traverse the DOM tree to the <th> elements - * and {@link Element#addClassName(String) adding} the class name as specified by the column, if not null. - * - * @author Axel Uhl (D043530) - */ -public class CellTableWithStylableHeaders extends CellTable { - public CellTableWithStylableHeaders(int pageSize, LeaderboardTableResources resources) { - super(pageSize, resources); - } - - @Override - protected void renderRowValues(SafeHtmlBuilder sb, List values, int start, - SelectionModel selectionModel) { - super.renderRowValues(sb, values, start, selectionModel); - Scheduler.get().scheduleFinally(new ScheduledCommand() { - @Override - public void execute() { - updateColumnHeaderStyles(); - } - }); - } - - private void updateColumnHeaderStyles() { - Element tableElement = getElement(); - Element thead = tableElement.getElementsByTagName("thead").getItem(0); - Node header = thead.getChild(0); // single tr header row - NodeList headerColumns = header.getChildNodes(); - for (int i=0; i) getColumn(i)).getHeaderStyle(); - if (headerStyle != null) { - headerCell.addClassName(headerStyle); - } - } - } - - @Override - public void redrawFooters() { - super.redrawFooters(); - updateColumnHeaderStyles(); - } - - @Override - public void redrawHeaders() { - super.redrawHeaders(); - updateColumnHeaderStyles(); - } - -} +package com.sap.sailing.gwt.ui.leaderboard; + +import java.util.List; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.NodeList; +import com.google.gwt.safehtml.shared.SafeHtmlBuilder; +import com.google.gwt.view.client.SelectionModel; + +/** + * Uses {@link SortableColumn#getHeaderStyle()} to optionally add a custom CSS style to the <th> table + * header cell for the respective column.

+ * + * The implementation works by overriding {@link #renderRowValues(SafeHtmlBuilder, List, int, SelectionModel)} which + * first calls the super implementation which is expected to render the header cells already into the implementation + * {@link Element}, then uses {@link #updateColumnHeaderStyles()} to traverse the DOM tree to the <th> elements + * and {@link Element#addClassName(String) adding} the class name as specified by the column, if not null. + * + * @author Axel Uhl (D043530) + */ +public class SortedCellTableWithStylableHeaders extends SortedCellTable { + public SortedCellTableWithStylableHeaders(int pageSize, LeaderboardTableResources resources) { + super(pageSize, resources); + } + + @Override + protected void renderRowValues(SafeHtmlBuilder sb, List values, int start, + SelectionModel selectionModel) { + super.renderRowValues(sb, values, start, selectionModel); + Scheduler.get().scheduleFinally(new ScheduledCommand() { + @Override + public void execute() { + updateColumnHeaderStyles(); + } + }); + } + + private void updateColumnHeaderStyles() { + Element tableElement = getElement(); + Element thead = tableElement.getElementsByTagName("thead").getItem(0); + Node header = thead.getChild(0); // single tr header row + NodeList headerColumns = header.getChildNodes(); + for (int i=0; i) getColumn(i)).getHeaderStyle(); + if (headerStyle != null) { + headerCell.addClassName(headerStyle); + } + } + } + + @Override + public void redrawFooters() { + super.redrawFooters(); + updateColumnHeaderStyles(); + } + + @Override + public void redrawHeaders() { + super.redrawHeaders(); + updateColumnHeaderStyles(); + } + +}