📄 uitree.java
字号:
package com.mycompany.jsf.component;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.FacesListener;
import javax.faces.event.PhaseId;
import com.mycompany.jsf.model.TreeNode;
import com.mycompany.jsf.model.TreeModel;
/**
* This class is a JSF component that represents a tree control.
* Facets named "openNode", "closedNode" and "leafNode" represent
* the components resposible for processing nodes of a TreeModel
* in all request processing lifecycle phases, and may be either
* input or output components. The class implements the NamingContainer
* interface to adjust the client IDs for the facets, so that a
* unique client ID is used for each node even though all nodes
* are in fact processed by one set of components.
* <p>
* The value of this component must be either a TreeModel or a
* TreeNode representing the root node of a tree.
* <p>
* The component is rendered by the "com.mycompany.Tree" renderer
* type by default.
*
* @author Hans Bergsten, Gefion Software <hans@gefionsoftware.com>
* @version 1.0
*/
public class UITree extends UIComponentBase implements NamingContainer {
public static final String COMPONENT_TYPE = "com.mycompany.Tree";
public static final String COMPONENT_FAMILY = "com.mycompany.Tree";
/**
* The component's value, either a TreeModel or a TreeNode instance.
*/
private Object value = null;
/**
* The TreeModel used by this component, either set explicitly as
* the value of created as a wrapper around a TreeNode value.
*/
private TreeModel model = null;
/**
* The current node ID.
*/
private String nodeId;
/**
* This map contains SavedState instances for each node in the
* tree, keyed by the client identifier of the component representing
* node, which contains the nodeId value for uniqueness.
*/
private Map saved = new HashMap();
/**
* The name of the request scope variable through which the data
* object for the current node is exposed.
*/
private String var = null;
/**
* The name of the request scope variable through which the node
* toggler object is exposed.
*/
private String varNodeToggler = null;
/**
* The NodeToggler instance.
*/
private NodeToggler nodeToggler;
/**
* Creates an instance and sets the renderer type to
* "com.mycompany.Tree".
*/
public UITree() {
super();
setRendererType("com.mycompany.Tree");
}
/**
* Returns the COMPONENT_TYPE value.
*/
public String getFamily() {
return (COMPONENT_FAMILY);
}
/**
* Returns the name of the request scope through which the data object
* for the current node is exposed.
*/
public String getVar() {
return var;
}
/**
* Sets the name of the request-scope variable through which the
* data object for the current node is exposed.
*/
public void setVar(String var) {
this.var = var;
}
/**
* Returns the name of the request scope through which the NodeToggler
* is exposed.
*/
public String getVarNodeToggler() {
return varNodeToggler;
}
/**
* Sets the name of the request scope through which the NodeToggler
* is exposed.
*/
public void setVarNodeToggler(String varNodeToggler) {
this.varNodeToggler = varNodeToggler;
}
/**
* Returns the single instance of the NodeToggler, creating it
* if needed.
*/
private NodeToggler getNodeToggler() {
if (nodeToggler == null) {
nodeToggler = new NodeToggler(this);
}
return nodeToggler;
}
/**
* Returns the "openNode" facet.
*/
public UIComponent getOpenNode() {
return getFacet("openNode");
}
/**
* Sets the "openNode" facet.
*/
public void setOpenNode(UIComponent openNode) {
getFacets().put("openNode", openNode);
}
/**
* Returns the "closedNode" facet.
*/
public UIComponent getClosedNode() {
return getFacet("closedNode");
}
/**
* Sets the "openNode" facet.
*/
public void setClosedNode(UIComponent closedNode) {
getFacets().put("closedNode", closedNode);
}
/**
* Returns the "leafNode" facet.
*/
public UIComponent getLeafNode() {
return getFacet("leafNode");
}
/**
* Sets the "leafNode" facet.
*/
public void setLeafNode(UIComponent closedNode) {
getFacets().put("leafNode", closedNode);
}
/**
* Returns the current node from the TreeModel, or "null" if
* no node is currently processed.
*/
public TreeNode getNode() {
if (getDataModel() == null) {
return null;
}
return (getDataModel().getNode());
}
/**
* Returns the current node ID, or "null" if no node is currently
* processed.
*/
public String getNodeId() {
return nodeId;
}
/**
* Sets the node ID, saving the state of all facet components
* for the previous node ID and restoring it for the new
* if it was saved for the new node ID previously, and exposes the
* node for the new node ID and the NodeToggler through their
* request scope variables.
*/
public void setNodeId(String nodeId) {
// Save current state for the previous node
saveDescendantState();
this.nodeId = nodeId;
TreeModel model = getDataModel();
if (model == null) {
return;
}
model.setNodeId(nodeId);
// Reset current state information for the new row index
restoreDescendantState();
// Clear or expose the current row data as a request scope attribute
Map requestMap =
getFacesContext().getExternalContext().getRequestMap();
if (var != null) {
if (nodeId == null) {
requestMap.remove(var);
} else {
requestMap.put(var, getNode());
}
}
if (varNodeToggler != null) {
if (nodeId == null) {
requestMap.remove(varNodeToggler);
} else {
requestMap.put(varNodeToggler, getNodeToggler());
}
}
}
/**
* Returns the component value, set explicitly or through a
* ValueBinding, or null if the value isn't set.
*/
public Object getValue() {
if (value != null) {
return value;
}
ValueBinding vb = getValueBinding("value");
if (vb != null) {
return (vb.getValue(getFacesContext()));
} else {
return null;
}
}
/**
* Sets the component value, either a TreeModel or a TreeNode,
* and resets the previously cached model, if any.
*/
public void setValue(Object value) {
this.model = null;
this.value = value;
}
/**
* Throws an IllegalArgumentException if the name is "var",
* "varToggler" or "nodeId" (these properties must be set
* to explicit values); otherwise, delegates to the superclass.
*/
public void setValueBinding(String name, ValueBinding binding) {
if ("value".equals(name)) {
model = null;
} else if ("var".equals(name) || "nodeId".equals(name) ||
"varNodeToggler".equals(name)) {
throw new IllegalArgumentException();
}
super.setValueBinding(name, binding);
}
/**
* Returns a client ID composed from the regular client ID
* (returned by the superclass getClientId() method) and the
* current node ID (if any) separated by a colon.
*/
public String getClientId(FacesContext context) {
String ownClientId = super.getClientId(context);
if (nodeId != null) {
return ownClientId + NamingContainer.SEPARATOR_CHAR + nodeId;
} else {
return ownClientId;
}
}
/**
* Wraps the event in a ChildEvent and calls the superclass method
* add it to the queue with this component as the event source.
*/
public void queueEvent(FacesEvent event) {
super.queueEvent(new ChildEvent(this, event, getNodeId()));
}
/**
* If the event is a ChildEvent, unwraps the real event, calls
* setNodeId() with the node ID in the ChildEvent and delegates
* the processing to the real event source.
*/
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (!(event instanceof ChildEvent)) {
super.broadcast(event);
return;
}
// Set up the correct context and fire our wrapped event
ChildEvent childEvent = (ChildEvent) event;
String currNodeId = getNodeId();
setNodeId(childEvent.getNodeId());
FacesEvent nodeEvent = childEvent.getFacesEvent();
nodeEvent.getComponent().broadcast(nodeEvent);
setNodeId(currNodeId);
return;
}
/**
* Before delegating to the superclass, resets the saved
* per-node state for facet input components unless it is
* needed to rerender the current page with errors, as
* determined by the keepSaved() method.
*/
public void encodeBegin(FacesContext context) throws IOException {
model = null; // Re-evaluate even with server-side state saving
if (!keepSaved(context)) {
saved = new HashMap();
}
super.encodeBegin(context);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -