Actually I would do this using a custom converter. Then you don't have
to decorate it.
You can have a
public class BooleanLabel {
...
IConverter getConverter() {
return new IConverter() {
...
}
}
}
In your converter decide how to display the value.
I don't think there is anything wrong with your model, just that the
custom components like this are IMHO easier to use.
-Matej
Logi Ragnarsson wrote:
> Hello everyone,
>
> I'm relatively new to wicket, but I'm building a web application where
> several
> forms are backed by compound models with boolean and enum constituent models.
> The straight-forward implementation of this would display true/false values,
> and the names of the enum values in the code, which is generally not very
> user friendly (peopel say "yes" and "no" and they don't generally put choices
> in all upper case) and not internationalized, so Something Must Be Done.
>
> I'd like to show my solution, with input from Igor Vaynberg, for comment and
> perhaps re-use. I've only got the boolean case implemented, but the enum case
> is basically more of the same with more localization resources needing to be
> loaded.
>
> The simplest case (and one not worth all this effort) is when displaying a
> boolean value in a ListView:
> new Label("active");
> which becomes:
> new Label("active", new I18nBooleanModelDecorator(item.getModel()));
> where the (attached) I18nBooleanModelDecorator has been applied to the model.
> This will display "yes" or "no" for the boolean values unless those strings
> have been replaced by setting the I18nBooleanModelDecorator.TRUE and
> I18nBooleanModelDecorator.FALSE licalization strings to something else.
>
> Usually on a form you'd use a check-box for setting boolean values, such as
> this:
> new CheckBox("active");
> but for illustrative purposes suppose we have this text field instead:
> new TextField("active");
> The following will work if the component's compound model has been set before
> the form is populated with fields and will not be changed later:
> new TextField("active", new I18nBooleanModelDecorator(getModel()));
> but in reality getModel() is likely to return null or to return a model which
> is later replaced with another in response to user or application events, so
> the text field would now either have no underlying model or an out-dated one.
>
> For this I wrote a ComponentModelDelegator which takes a Component and
> delegates all model operations to the current model of that component like
> so:
> IModel model = new ComponentModelDelegator(this)
> new TextField("active", new I18nBooleanModelDecorator(model));
>
> This works like a charm and you can write "nei" in my Icelandic locale to set
> the value of the active property of my underlying model to false... before
> you then change the code back to using the much more reasonable CheckBox
> class.
>
> Is there anything terribly wrong with this? Would this be useful for other
> wicket users, probably in combination with the similar decorator for
> enumerations?
>
> PS The attached code is hereby published under the Apache license.
>
>
> ------------------------------------------------------------------------
>
> package is.gig.wicket.models;
>
> import org.apache.log4j.Logger;
> import wicket.Component;
> import wicket.model.IModel;
>
> /** Model which delegates to the model of a given component. */
> public class ComponentModelDelegator/*T*/
> implements IModel/*T*/
> {
> private static final Logger LOG =
> Logger.getLogger(ComponentModelDelegator.class);
>
> private Component component;
>
> /** Create a new delegator to the model of the givne component. */
> public ComponentModelDelegator(Component component) {
> this.component = component;
> }
>
> public Component getComponent() {
> return component;
> }
>
> public void setComponent(Component component) {
> this.component = component;
> }
>
> public IModel /*T*/ getNestedModel() {
> return component.getModel();
> }
>
> public Object getObject(final Component component) {
> IModel nested = getNestedModel();
> if (nested != null) {
> return nested.getObject(component);
> } else {
> return null;
> }
> }
>
> public void setObject(final Component component, final Object object) {
> IModel nested = getNestedModel();
> if (nested != null) {
> nested.setObject(component, object);
> }
> }
>
> public void detach() {
> IModel nested = getNestedModel();
> if (nested != null) nested.detach();
> }
> }
>
>
> ------------------------------------------------------------------------
>
> package is.gig.wicket.models.i18n;
>
> import wicket.Component;
> import wicket.model.IModel;
>
> /**
> * Decorator for a boolean model which converts to and from localized and
> human-friendly display values, falling back to
> * "yes" and "no".
> *
> * <p/>The display values are taken from the localization strings with keys
> <code>I18nBooleanModelDecorator.TRUE</code>
> * and <code>I18nBooleanModelDecorator.FALSE</code> respectively.
> */
> public class I18nBooleanModelDecorator
> implements IModel/*Boolean*/
> {
> private static final String I18N_KEY_PREFIX = "I18nBooleanModelDecorator";
>
> private IModel /*Boolean*/ nestedModel;
> private Boolean defaultValue = Boolean.FALSE;
>
> // CONSTRUCTION AND CONFIGURATION
>
> /**
> * Create a new i18n decorator.
> *
> * @param nestedModel the model to decorate
> * @param defaultValue the value to set in the nested model if the
> display string being set is not recognized.
> */
> public I18nBooleanModelDecorator(IModel /*Boolean*/ nestedModel, Boolean
> defaultValue) {
> this.defaultValue = defaultValue;
> this.nestedModel = nestedModel;
> }
>
> /**
> * Create a new i18n decorator.
> *
> * @param nestedModel the model to decorate
> */
> public I18nBooleanModelDecorator(IModel /*Boolean*/ nestedModel) {
> this(nestedModel, Boolean.FALSE);
> }
>
> public IModel /*Boolean*/ getNestedModel() {
> return nestedModel;
> }
>
> public void setNestedModel(IModel /*Boolean*/ nestedModel) {
> this.nestedModel = nestedModel;
> }
>
> /** et the value used in the nested model if the display string being set
> is not recognized. */
> public Boolean getDefaultValue() {
> return defaultValue;
> }
>
> /** Set the value to set in the nested model if the display string being
> set is not recognized. */
> public void setDefaultValue(Boolean defaultValue) {
> this.defaultValue = defaultValue;
> }
>
> // MODEL IMPLEMENTATION
>
> private String getHumanReadableValue(Component component, boolean b) {
> if (b) {
> return component.getString(I18N_KEY_PREFIX + ".TRUE",
> nestedModel, "yes");
> } else {
> return component.getString(I18N_KEY_PREFIX + ".FALSE",
> nestedModel, "no");
> }
> }
>
> public Object getObject(final Component component) {
> Boolean b = (Boolean) nestedModel.getObject(component);
> if (b == null) return null;
> return getHumanReadableValue(component, b.booleanValue());
> }
>
> public void setObject(final Component component, final Object object) {
> if (object == null) nestedModel.setObject(component, null);
> String str = object.toString();
> if (getHumanReadableValue(component, true).equalsIgnoreCase(str)) {
> nestedModel.setObject(component, Boolean.TRUE);
> } else if (getHumanReadableValue(component,
> false).equalsIgnoreCase(str)) {
> nestedModel.setObject(component, Boolean.FALSE);
> } else {
> nestedModel.setObject(component, defaultValue);
> }
> }
>
> public void detach() {
> nestedModel.detach();
> }
> }
>
>
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Wicket-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/wicket-user
--
get professional wicket training and consultation
http://www.wicket-support.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user