001: package wicket.examples.ajax.builtin;
002:
003: import java.io.Serializable;
004:
005: import wicket.ResourceReference;
006: import wicket.ajax.AjaxRequestTarget;
007: import wicket.extensions.rating.RatingPanel;
008: import wicket.markup.html.link.Link;
009: import wicket.model.IModel;
010: import wicket.model.Model;
011: import wicket.model.PropertyModel;
012:
013: /**
014: * Demo page for the rating component.
015: *
016: * @author Martijn Dashorst
017: */
018: public class RatingsPage extends BasePage {
019: /**
020: * Star image for no selected star
021: */
022: public static final ResourceReference WICKETSTAR0 = new ResourceReference(
023: RatingsPage.class, "WicketStar0.png");
024:
025: /**
026: * Star image for selected star
027: */
028: public static final ResourceReference WICKETSTAR1 = new ResourceReference(
029: RatingsPage.class, "WicketStar1.png");
030:
031: /** For serialization. */
032: private static final long serialVersionUID = 1L;
033:
034: /**
035: * Link to reset the ratings.
036: */
037: private final class ResetRatingLink extends Link {
038: /** For serialization. */
039: private static final long serialVersionUID = 1L;
040:
041: /**
042: * Constructor.
043: *
044: * @param id
045: * component id
046: * @param object
047: * the model to reset.
048: */
049: public ResetRatingLink(String id, IModel object) {
050: super (id, object);
051: }
052:
053: /**
054: * @see Link#onClick()
055: */
056: public void onClick() {
057: RatingModel rating = (RatingModel) getModelObject();
058: rating.nrOfVotes = 0;
059: rating.rating = 0;
060: rating.sumOfRatings = 0;
061: }
062: }
063:
064: /**
065: * Rating model for storing the ratings, typically this comes from a
066: * database.
067: */
068: public static class RatingModel implements Serializable {
069: private int nrOfVotes = 0;
070: private int sumOfRatings = 0;
071: private double rating = 0;
072:
073: /**
074: * Returns whether the star should be rendered active.
075: *
076: * @param star
077: * the number of the star
078: * @return true when the star is active
079: */
080: public boolean isActive(int star) {
081: return star < ((int) (rating + 0.5));
082: }
083:
084: /**
085: * Gets the number of cast votes.
086: *
087: * @return the number of cast votes.
088: */
089: public Integer getNrOfVotes() {
090: return new Integer(nrOfVotes);
091: }
092:
093: /**
094: * Adds the vote from the user to the total of votes, and calculates the
095: * rating.
096: *
097: * @param nrOfStars
098: * the number of stars the user has cast
099: */
100: public void addRating(int nrOfStars) {
101: nrOfVotes++;
102: sumOfRatings += nrOfStars;
103: rating = sumOfRatings / (1.0 * nrOfVotes);
104: }
105:
106: /**
107: * Gets the rating.
108: *
109: * @return the rating
110: */
111: public Double getRating() {
112: return new Double(rating);
113: }
114:
115: /**
116: * Returns the sum of the ratings.
117: *
118: * @return the sum of the ratings.
119: */
120: public int getSumOfRatings() {
121: return sumOfRatings;
122: }
123: }
124:
125: /**
126: * static models for the ratings, not thread safe, but in this case, we
127: * don't care.
128: */
129: private static RatingModel rating1 = new RatingModel();
130:
131: /**
132: * static model for the ratings, not thread safe, but in this case, we don't
133: * care.
134: */
135: private static RatingModel rating2 = new RatingModel();
136:
137: /**
138: * keeps track whether the user has already voted on this page, comes
139: * typically from the database, or is stored in a cookie on the client side.
140: */
141: private Boolean hasVoted = Boolean.FALSE;
142:
143: /**
144: * Constructor.
145: */
146: public RatingsPage() {
147: add(new RatingPanel("rating1", new PropertyModel(rating1,
148: "rating"), 5, new PropertyModel(rating1, "nrOfVotes"),
149: true) {
150: protected boolean onIsStarActive(int star) {
151: return RatingsPage.rating1.isActive(star);
152: }
153:
154: protected void onRated(int rating, AjaxRequestTarget target) {
155: RatingsPage.rating1.addRating(rating);
156: }
157: });
158: add(new RatingPanel("rating2", new PropertyModel(rating2,
159: "rating"), new Model(new Integer(5)),
160: new PropertyModel(rating2, "nrOfVotes"),
161: new PropertyModel(this , "hasVoted"), true) {
162: protected String getActiveStarUrl(int iteration) {
163: return getRequestCycle().urlFor(WICKETSTAR1).toString();
164: }
165:
166: protected String getInactiveStarUrl(int iteration) {
167: return getRequestCycle().urlFor(WICKETSTAR0).toString();
168: }
169:
170: protected boolean onIsStarActive(int star) {
171: return RatingsPage.rating2.isActive(star);
172: }
173:
174: protected void onRated(int rating, AjaxRequestTarget target) {
175: // make sure the user can't vote again
176: hasVoted = Boolean.TRUE;
177: RatingsPage.rating2.addRating(rating);
178: }
179: });
180: add(new ResetRatingLink("reset1", new Model(rating1)));
181: add(new ResetRatingLink("reset2", new Model(rating2)));
182: }
183:
184: /**
185: * Getter for the hasVoted flag.
186: *
187: * @return <code>true</code> when the user has already voted.
188: */
189: public Boolean getHasVoted() {
190: return hasVoted;
191: }
192: }
|