public boolean visitTree(VisitContext context, VisitCallback callback)context is an instance of VisitContext class that is used to hold state relating to performing a component tree visit. callback is an instance of VisitCallback whose visit method will be called for each node visited. Let's start with a practical example. Our task is to find and gather all components implementing EditableValueHolder. Such components implement resetValue() method which allows to reset component's submitted, locale values, etc. to an un-initialized state. Furthermore, another requirement is to skip sub-tree traversal for a component which should be not rendered (don't visit sub-components). In other words we want to find only editable components to be rendered. Assume, the start component calls target
UIComponent target = ...It can be got in an action / event listener by event.getComponent() or somewhere else by findComponent().
We are ready now to create a special EditableValueHoldersVisitCallback in order to find all mentioned above sub-components and call visitTree on the target component with this callback. EditableValueHoldersVisitCallback gathers sub-components we want to reset.
EditableValueHoldersVisitCallback visitCallback = new EditableValueHoldersVisitCallback(); target.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), visitCallback); // iterate over found sub-components and reset their values List<EditableValueHolder> editableValueHolders = visitCallback.getEditableValueHolders(); for (EditableValueHolder editableValueHolder : editableValueHolders) { editableValueHolder.resetValue(); }Callback looks like this one
public class EditableValueHoldersVisitCallback implements VisitCallback { private List<EditableValueHolder> editableValueHolders = new ArrayList<EditableValueHolder>(); @Override public VisitResult visit(final VisitContext context, final UIComponent target) { if (!target.isRendered()) { return VisitResult.REJECT; } if (target instanceof EditableValueHolder) { editableValueHolders.add((EditableValueHolder) target); } return VisitResult.ACCEPT; } public List<EditableValueHolder> getEditableValueHolders() { return editableValueHolders; } }Result VisitResult.REJECT indicates that the tree visit should be continued, but should skip the current component's subtree (remember our requirement?). VisitResult.ACCEPT indicates that the tree visit should descend into current component's subtree. There is also VisitResult.COMPLETE as return value if the tree visit should be terminated.
Some components extending UINamingContainer override the behavior of visitTree(). For instance, UIData overrides this method to handle iteration correctly.