Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

It often occurs that multiple wicket behaviors must be used to obtain a certain effect. An example can be a tooltip that requires both a javascript header contribution and an attribute modifier. Another example is that of a confirmation popup when someone clicks on an certain button. Using a composite behavior, which is an example of the composite design pattern, it is posisble possible to realize things like this by adding just a single composite behavior object to a component (e.g. ToolTipBehavior, ConfirmationBehavior) instead of having to add multiple behaviors just to obtain one effect in the user interface. This enhances readability and maintainability of the code.

...

Composite behavior, first attempt

A solution is to use the composite design pattern and create a composite behavior is fairly easy to implement. .
This can be done as follows:

No Format
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import wicket.Component;
import wicket.Response;
import wicket.behavior.IBehavior;
import wicket.markup.ComponentTag;
import wicket.markup.html.IHeaderContributor;

/**
 * Represents a composite behavior allowing the user to attach multiple behaviors to a 
 * component at once. 
 *
 */
public class CompositeBehavior implements IBehavior, IHeaderContributor {
	
	private List<IBehavior> _behaviors; 
	
	public CompositeBehavior(IBehavior[] aBehaviors) { 
		_behaviors = new ArrayList<IBehavior>(Arrays.asList(aBehaviors));
	}
	
	public void add(IBehavior aBehavior) { 
		_behaviors.add(aBehavior);
	}

	public void bind(Component aComponent) {
		for (IBehavior behavior: _behaviors) { 
			behavior.bind(aComponent);
		}
	}

	public void detachModel(Component aComponent) {
		for (IBehavior behavior: _behaviors) { 
			behavior.detachModel(aComponent);
		}
	}

	public void exception(Component aComponent, RuntimeException aException) {
		for (IBehavior behavior: _behaviors) { 
			behavior.exception(aComponent, aException);
		}
	}

	public void onComponentTag(Component aComponent, ComponentTag aTag) {
		for (IBehavior behavior: _behaviors) { 
			behavior.onComponentTag(aComponent, aTag);
		}
	}

	public void rendered(Component aComponent) {
		for (IBehavior behavior: _behaviors) { 
			behavior.rendered(aComponent);
		}
	}

	public void renderHead(Response aResponse) {
		for (IBehavior behavior: _behaviors) {
			if ( behavior instanceof IHeaderContributor) { 
			    ((IHeaderContributor)behavior).renderHead(aResponse);
			}
		}
	}

}

...