The default implementation of FeedbackPanel displays messages unsorted.
You can sort messages any way you like by either setting the sortingComparator property of
FeedbackPanel, or to provide a custom implementation of the FeedbackMessagesModel by overriding
FeedbackPanel.getFeedbackMessagesModel().
As an example, let's say we want to sort the messages in the order that we added our components
to a form. For this example, we alter the FormInput example of wicket-examples.
First, use a variable (like a list) to store your order:
Code Block |
---|
private List componentOrder = new ArrayList(); |
Then, override method add to automatically add the order:
Code Block |
---|
/** * @see wicket.MarkupContainer#add(wicket.Component) */ public MarkupContainer add(Component component) { super.add(component); componentOrder.add(component); return (MarkupContainer)component; } |
Now, create a comparator that uses this and set it on the FeedbackPanel:
Code Block |
---|
feedback.setSortingComparator(new Comparator() { public int compare(Object o1, Object o2) { FeedbackMessage m1 = (FeedbackMessage)o1; FeedbackMessage m2 = (FeedbackMessage)o2; int ix1 = componentOrder.indexOf(m1.getReporter()); int ix2 = componentOrder.indexOf(m2.getReporter()); return ix1 - ix2; } }); |
That's it! The complete patched version of FormInput (based on v1.41):
Code Block |
---|
package wicket.examples.forminput; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Locale; import wicket.Component; import wicket.FeedbackMessage; import wicket.MarkupContainer; import wicket.examples.WicketExamplePage; import wicket.markup.html.form.CheckBox; import wicket.markup.html.form.DropDownChoice; import wicket.markup.html.form.Form; import wicket.markup.html.form.ImageButton; import wicket.markup.html.form.ListMultipleChoice; import wicket.markup.html.form.RadioChoice; import wicket.markup.html.form.RequiredTextField; import wicket.markup.html.form.TextField; import wicket.markup.html.form.model.ChoiceList; import wicket.markup.html.form.model.IChoice; import wicket.markup.html.form.validation.IntegerValidator; import wicket.markup.html.image.Image; import wicket.markup.html.link.Link; import wicket.markup.html.panel.FeedbackPanel; import wicket.model.CompoundPropertyModel; import wicket.model.PropertyModel; import wicket.protocol.http.WebRequest; import wicket.util.convert.IConverter; /** * Example for form input. * * @author Eelco Hillenius * @author Jonathan Locke */ public class FormInput extends WicketExamplePage { /** Relevant locales wrapped in a list. */ private static final List LOCALES = Arrays.asList(new Locale[] { Locale.US, new Locale("nl"), Locale.GERMANY , Locale.SIMPLIFIED_CHINESE }); /** available numbers for the radio selection. */ private static final List NUMBERS = Arrays.asList(new String[]{"1", "2", "3"}); /** available sites for the multiple select. */ private static final List SITES = Arrays.asList( new String[]{"The Server Side", "Java Lobby", "Java.Net"}); /** * Constructor */ public FormInput() { Locale locale = getLocale(); // Construct form and feedback panel and hook them up final FeedbackPanel feedback = new FeedbackPanel("feedback"); add(feedback); add(new InputForm("inputForm", feedback)); // Dropdown for selecting locale add(new LocaleDropDownChoice("localeSelect")); // Link to return to default locale add(new Link("defaultLocaleLink") { public void onClick() { WebRequest request = (WebRequest)getRequest(); setLocale(request.getLocale()); } }); } /** * Sets locale for the user's session (getLocale() is inherited from * Component) * * @param locale * The new locale */ public void setLocale(Locale locale) { getSession().setLocale(locale); } /** * Form for collecting input. */ private class InputForm extends Form { /** * Keeps the add order for sorting messages. */ private List componentOrder = new ArrayList(); /** * Construct. * * @param name * Component name * @param feedback * Feedback display for form */ public InputForm(String name, FeedbackPanel feedback) { super(name, new CompoundPropertyModel(new FormInputModel()), feedback); feedback.setSortingComparator(new Comparator() { public int compare(Object o1, Object o2) { FeedbackMessage m1 = (FeedbackMessage)o1; FeedbackMessage m2 = (FeedbackMessage)o2; int ix1 = componentOrder.indexOf(m1.getReporter()); int ix2 = componentOrder.indexOf(m2.getReporter()); return ix1 - ix2; } }); add(new RequiredTextField("stringProperty")); add(new RequiredTextField("integerProperty", Integer.class)); add(new RequiredTextField("doubleProperty", Double.class)); add(new RequiredTextField("dateProperty", Date.class)); add(new RequiredTextField("integerInRangeProperty", Integer.class).add(IntegerValidator .range(0, 100))); add(new CheckBox("booleanProperty")); add(new RadioChoice("numberRadioChoice", NUMBERS) { protected String getSuffix() { return ""; } }); add(new ListMultipleChoice("siteSelection", SITES)); // as an example, we use a custom converter here. add(new TextField("urlProperty", URL.class) { public IConverter getConverter() { return new URLConverter(); } }); add(new ImageButton("saveButton")); add(new Link("resetButtonLink") { public void onClick() { // just call modelChanged so that any invalid input is cleared. InputForm.this.modelChanged(); } }.add(new Image("resetButtonImage"))); } /** * @see wicket.markup.html.form.Form#onSubmit() */ public void onSubmit() { // Form validation successful. Display message showing edited model. info("Saved model " + getModelObject()); } /** * @see wicket.MarkupContainer#add(wicket.Component) */ public MarkupContainer add(Component component) { super.add(component); componentOrder.add(component); return (MarkupContainer)component; } } /** * Dropdown with Locales. */ private final class LocaleDropDownChoice extends DropDownChoice { /** * Construct. * @param id component id */ public LocaleDropDownChoice(String id) { super(id); // set the model that gets the current locale, and that is used for updating // the current locale to property 'locale' of FormInput setModel(new PropertyModel(FormInput.this, "locale")); // use a custom implementation of choices, as we want to display // the choices localized ChoiceList locales = new ChoiceList(LOCALES) { protected IChoice newChoice(Object object, int index) { return new LocaleChoice((Locale)object, index); } }; setChoices(locales); } /** * @see wicket.markup.html.form.DropDownChoice#wantOnSelectionChangedNotifications() */ protected boolean wantOnSelectionChangedNotifications() { // we want roundtrips when a the user selects another item return true; } /** * @see wicket.markup.html.form.DropDownChoice#onSelectionChanged(java.lang.Object) */ public void onSelectionChanged(Object newSelection) { // note that we don't have to do anything here, as our property model allready // calls FormInput.setLocale when the model is updated // setLocale((Locale)newSelection); // so we don't need to do this } } /** * Choice for a locale. */ private final class LocaleChoice implements IChoice { /** The index of the choice. */ private final int index; /** The choice model object. */ private final Locale locale; /** * Constructor. * @param locale The locale * @param index The index of the object in the choice list */ public LocaleChoice(final Locale locale, final int index) { this.locale = locale; this.index = index; } /** * @see wicket.markup.html.form.model.IChoice#getDisplayValue() */ public String getDisplayValue() { String display = locale.getDisplayName(getLocale()); return display; } /** * @see wicket.markup.html.form.model.IChoice#getId() */ public String getId() { return Integer.toString(index); } /** * @see wicket.markup.html.form.model.IChoice#getObject() */ public Object getObject() { return locale; } } } |