[richfaces-issues] [JBoss JIRA] Updated: (RF-3569) <rich:tree> possible performance issue
Ilya Shaikovsky (JIRA)
jira-events at lists.jboss.org
Wed May 28 08:54:49 EDT 2008
[ http://jira.jboss.com/jira/browse/RF-3569?page=all ]
Ilya Shaikovsky updated RF-3569:
--------------------------------
Fix Version/s: (was: 3.2.0.SR1)
Description:
i've got an quite simple tree with "just" 50 elements �¡ 200 childs -> 10.000 nodes
every node gots:
- some little text
- image for a checkbox via h:graphicImage
- a4j:support for listenersupport at the image
expanding/collapsing nodes and checking the checkboxes takes a lot of time...
jprofiler tells me that most of the time is spend by domparsing. i dont know if i handle the tree as intended. here is some code:
JSP
[code]
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<title>tree</title>
</head>
<body>
<f:view>
<h:form>
<a4j:loadStyle src="/res/button.css" />
<a4j:loadStyle src="/res/tree/style.css" />
<a4j:commandButton id="show_me" value="show childs" styleClass="normalButton">
<a4j:ajaxListener type="controller.listener.ListenerBean" />
</a4j:commandButton>
<h:panelGrid columns="2">
<h:outputLabel>
<h:outputText value="infinite Tree extended"></h:outputText>
<rich:tree componentState="#{treeBean.treeState}" id="infinite_Tree_expanded" style="width:300px" switchType="ajax" stateAdvisor="#{treeDemoStateAdvisor}">
<rich:recursiveTreeNodesAdaptor roots="#{treeBean.rootNodes}" var="item" nodes="#{item.children}">
<rich:treeNode nodeSelectListener="#{treeBean.processSelection}">
<h:graphicImage value="/res/tree/chkb_#{item.state}.png">
<a4j:support event="onclick" reRender="infinite_Tree_expanded" actionListener="#{item.actionListener}"/>
</h:graphicImage>
<h:outputText value="#{item.value} - #{item.state}"/>
</rich:treeNode>
</rich:recursiveTreeNodesAdaptor>
</rich:tree>
</h:outputLabel>
</h:panelGrid>
</h:form>
</f:view>
</body>
</html>[/code]
TreeBean:
[code]package my_tree;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import org.richfaces.component.state.TreeState;
import org.richfaces.event.NodeSelectedEvent;
public class TreeBean {
private TreeNode rootNode = null;
private TreeNode[] rootNodes = null;
private TreeState treeState;
private static final String DATA_PATH = "/res/tree/simple-tree-data.properties";
public TreeNode getRootNode() {
if (rootNode == null) {
loadTree();
}
return rootNode;
}
public void setRootNode(TreeNode rootNode) {
this.rootNode = rootNode;
}
public TreeNode[] getRootNodes() {
if (rootNodes == null) {
rootNodes = this.getRootNode().getChildren();
}
return rootNodes;
}
public void setRootNodes(TreeNode[] rootNodes) {
this.rootNodes = rootNodes;
}
public TreeState getTreeState() {
return treeState;
}
public void setTreeState(TreeState treeState) {
this.treeState = treeState;
}
private void addNodes(String path, TreeNode node, Properties properties) {
boolean end = false;
int counter = 1;
while (!end) {
String key = path != null ? path + '.' + counter : String
.valueOf(counter);
String value = properties.getProperty(key);
if (value != null) {
TreeNode newNode = new TreeNode(value);
newNode.setParent(node);
node.addNode(newNode);
addNodes(key, newNode, properties);
counter++;
} else {
end = true;
}
}
}
private void loadTree() {
System.out.println("TreeBean -> loadTree()");
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
InputStream dataStream = externalContext.getResourceAsStream(DATA_PATH);
try {
Properties properties = new Properties();
properties.load(dataStream);
rootNode = new TreeNode("root");
addNodes(null, rootNode, properties);
// manual tree extension
TreeNode dummy = new TreeNode("Sichtlinie");
int count = 0;
for (int i = 1; i <= 50; i++) {
count++;
TreeNode node = new TreeNode("i" + i);
for (int j = 1; j <= 200; j++) {
count++;
if (count % 1000 == 0) {
System.out.println(count);
}
TreeNode child = new TreeNode("j" + j);
child.setParent(node);
node.addNode(child);
}
node.setParent(dummy);
dummy.addNode(node);
}
rootNode.addNode(dummy);
} catch (IOException e) {
e.printStackTrace();
throw new FacesException(e.getMessage(), e);
} finally {
if (dataStream != null) {
try {
dataStream.close();
} catch (IOException e) {
e.printStackTrace();
externalContext.log(e.getMessage(), e);
}
}
}
}
public void processSelection(NodeSelectedEvent arg0)
throws AbortProcessingException {
System.out.println("SimpleTreeBean -> processSelection fired by "
+ arg0.getComponent().getId());
}[/code]
TreeNode:
[code]package my_tree;
import javax.faces.event.ActionEvent;
import org.richfaces.model.TreeNodeImpl;
public class TreeNode{
private String value;
private String state;
private TreeNode parent;
private TreeNode[] children;
public TreeNode(String value) {
this.value = value;
this.state = "";
}
public synchronized void addNode(TreeNode newChild) {
System.out.println("addNode("+newChild.getValue()+")");
if (this.children == null) {
TreeNode[] merged = new TreeNode[1];
merged[0] = newChild;
this.children = merged;
} else {
TreeNode[] merged = new TreeNode[this.children.length + 1];
int i;
for (i = 0; i < this.children.length; i++) {
merged[i] = this.children[i];
}
merged[merged.length - 1] = newChild;
this.children = merged;
}
}
public synchronized void addNodes(TreeNode[] newChildren) {
System.out.println("addNodeS("+newChildren.length+")");
TreeNode[] merged = new TreeNode[newChildren.length
+ this.children.length];
int i;
for (i = 0; i <= this.children.length; i++) {
merged[i] = this.children[i];
}
for (int i2 = i; i2 <= newChildren.length + i; i2++) {
merged[i2] = newChildren[i2];
}
this.children = merged;
}
public synchronized void removeNodes(TreeNode[] removeChildren) {
TreeNode[] splitted = new TreeNode[this.children.length
- removeChildren.length];
int pos = 0;
for (int i = 0; i <= this.children.length; i++) {
boolean contains = false;
for (int j = 0; j <= removeChildren.length; j++) {
if (this.children[i] == removeChildren[j]) {
contains = true;
}
}
if (contains == false) {
splitted[pos] = this.children[i];
pos++;
}
}
}
public String checkSibling(){
//System.out.println("checkSibling() of "+this.value);
if(this.children!=null){
String state = null;
int checked = 0;
int sub = 0;
int i;
TreeNode[] siblings = this.children;
for (i = 0; i < siblings.length; i++) {
TreeNode treeNode = siblings[i];
//System.out.println("\t"+treeNode.getValue()+" - "+treeNode.getState());
if(!treeNode.getState().equals("")){
if(treeNode.getState().equals("checked")){
checked++;
} else if(treeNode.getState().equals("sub")){
sub++;
}
}
}
if(checked == i){
state = "checked";
} else if(sub > 0 || checked > 0) {
state = "sub";
} else {
state = "";
}
//System.out.println("siblings: "+i+" (checked: "+checked+" sub: "+sub+") -> "+state);
return state;
} else {
return "";
}
}
public void setChildsChecked(TreeNode node){
//System.out.println("TreeNode -> setChildsChecked of "+node.getValue());
if(node.getChildren()!=null){
TreeNode[] children = node.getChildren();
for (int i = 0; i < children.length; i++) {
TreeNode treeNode = children[i];
treeNode.setState("checked");
setChildsChecked(treeNode);
}
}
}
public void setChildsUnchecked(TreeNode node){
//System.out.println("TreeNode -> setChildsUnchecked of "+node.getValue());
if(node.getChildren()!=null){
TreeNode[] children = node.getChildren();
for (int i = 0; i < children.length; i++) {
TreeNode treeNode = children[i];
treeNode.setState("");
setChildsUnchecked(treeNode);
}
}
}
public void setParentsState(TreeNode node){
System.out.println("TreeNode -> setParentsState of "+node.getValue());
node.setState(node.checkSibling());
if(node.getParent()!=null){
setParentsState(node.getParent());
}
}
public void actionListener(ActionEvent ae){
//System.out.println("TreeNode -> nodeListener fired by "+ae.getComponent().getId());
if(this.state == "checked"){
this.state = "";
setChildsUnchecked(this);
} else {
this.state = "checked";
setChildsChecked(this);
}
if(this.parent!=null){
setParentsState(this.parent);
}
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public TreeNode[] getChildren() {
return children;
}
public void setChildren(TreeNode[] children) {
this.children = children;
}
public TreeNode getParent() {
if(parent==null){
return null;
} else {
return parent;
}
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
[/code]
was:
i've got an quite simple tree with "just" 50 elements á 200 childs -> 10.000 nodes
every node gots:
- some little text
- image for a checkbox via h:graphicImage
- a4j:support for listenersupport at the image
expanding/collapsing nodes and checking the checkboxes takes a lot of time...
jprofiler tells me that most of the time is spend by domparsing. i dont know if i handle the tree as intended. here is some code:
JSP
[code]
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<title>tree</title>
</head>
<body>
<f:view>
<h:form>
<a4j:loadStyle src="/res/button.css" />
<a4j:loadStyle src="/res/tree/style.css" />
<a4j:commandButton id="show_me" value="show childs" styleClass="normalButton">
<a4j:ajaxListener type="controller.listener.ListenerBean" />
</a4j:commandButton>
<h:panelGrid columns="2">
<h:outputLabel>
<h:outputText value="infinite Tree extended"></h:outputText>
<rich:tree componentState="#{treeBean.treeState}" id="infinite_Tree_expanded" style="width:300px" switchType="ajax" stateAdvisor="#{treeDemoStateAdvisor}">
<rich:recursiveTreeNodesAdaptor roots="#{treeBean.rootNodes}" var="item" nodes="#{item.children}">
<rich:treeNode nodeSelectListener="#{treeBean.processSelection}">
<h:graphicImage value="/res/tree/chkb_#{item.state}.png">
<a4j:support event="onclick" reRender="infinite_Tree_expanded" actionListener="#{item.actionListener}"/>
</h:graphicImage>
<h:outputText value="#{item.value} - #{item.state}"/>
</rich:treeNode>
</rich:recursiveTreeNodesAdaptor>
</rich:tree>
</h:outputLabel>
</h:panelGrid>
</h:form>
</f:view>
</body>
</html>[/code]
TreeBean:
[code]package my_tree;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import org.richfaces.component.state.TreeState;
import org.richfaces.event.NodeSelectedEvent;
public class TreeBean {
private TreeNode rootNode = null;
private TreeNode[] rootNodes = null;
private TreeState treeState;
private static final String DATA_PATH = "/res/tree/simple-tree-data.properties";
public TreeNode getRootNode() {
if (rootNode == null) {
loadTree();
}
return rootNode;
}
public void setRootNode(TreeNode rootNode) {
this.rootNode = rootNode;
}
public TreeNode[] getRootNodes() {
if (rootNodes == null) {
rootNodes = this.getRootNode().getChildren();
}
return rootNodes;
}
public void setRootNodes(TreeNode[] rootNodes) {
this.rootNodes = rootNodes;
}
public TreeState getTreeState() {
return treeState;
}
public void setTreeState(TreeState treeState) {
this.treeState = treeState;
}
private void addNodes(String path, TreeNode node, Properties properties) {
boolean end = false;
int counter = 1;
while (!end) {
String key = path != null ? path + '.' + counter : String
.valueOf(counter);
String value = properties.getProperty(key);
if (value != null) {
TreeNode newNode = new TreeNode(value);
newNode.setParent(node);
node.addNode(newNode);
addNodes(key, newNode, properties);
counter++;
} else {
end = true;
}
}
}
private void loadTree() {
System.out.println("TreeBean -> loadTree()");
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
InputStream dataStream = externalContext.getResourceAsStream(DATA_PATH);
try {
Properties properties = new Properties();
properties.load(dataStream);
rootNode = new TreeNode("root");
addNodes(null, rootNode, properties);
// manual tree extension
TreeNode dummy = new TreeNode("Sichtlinie");
int count = 0;
for (int i = 1; i <= 50; i++) {
count++;
TreeNode node = new TreeNode("i" + i);
for (int j = 1; j <= 200; j++) {
count++;
if (count % 1000 == 0) {
System.out.println(count);
}
TreeNode child = new TreeNode("j" + j);
child.setParent(node);
node.addNode(child);
}
node.setParent(dummy);
dummy.addNode(node);
}
rootNode.addNode(dummy);
} catch (IOException e) {
e.printStackTrace();
throw new FacesException(e.getMessage(), e);
} finally {
if (dataStream != null) {
try {
dataStream.close();
} catch (IOException e) {
e.printStackTrace();
externalContext.log(e.getMessage(), e);
}
}
}
}
public void processSelection(NodeSelectedEvent arg0)
throws AbortProcessingException {
System.out.println("SimpleTreeBean -> processSelection fired by "
+ arg0.getComponent().getId());
}[/code]
TreeNode:
[code]package my_tree;
import javax.faces.event.ActionEvent;
import org.richfaces.model.TreeNodeImpl;
public class TreeNode{
private String value;
private String state;
private TreeNode parent;
private TreeNode[] children;
public TreeNode(String value) {
this.value = value;
this.state = "";
}
public synchronized void addNode(TreeNode newChild) {
System.out.println("addNode("+newChild.getValue()+")");
if (this.children == null) {
TreeNode[] merged = new TreeNode[1];
merged[0] = newChild;
this.children = merged;
} else {
TreeNode[] merged = new TreeNode[this.children.length + 1];
int i;
for (i = 0; i < this.children.length; i++) {
merged[i] = this.children[i];
}
merged[merged.length - 1] = newChild;
this.children = merged;
}
}
public synchronized void addNodes(TreeNode[] newChildren) {
System.out.println("addNodeS("+newChildren.length+")");
TreeNode[] merged = new TreeNode[newChildren.length
+ this.children.length];
int i;
for (i = 0; i <= this.children.length; i++) {
merged[i] = this.children[i];
}
for (int i2 = i; i2 <= newChildren.length + i; i2++) {
merged[i2] = newChildren[i2];
}
this.children = merged;
}
public synchronized void removeNodes(TreeNode[] removeChildren) {
TreeNode[] splitted = new TreeNode[this.children.length
- removeChildren.length];
int pos = 0;
for (int i = 0; i <= this.children.length; i++) {
boolean contains = false;
for (int j = 0; j <= removeChildren.length; j++) {
if (this.children[i] == removeChildren[j]) {
contains = true;
}
}
if (contains == false) {
splitted[pos] = this.children[i];
pos++;
}
}
}
public String checkSibling(){
//System.out.println("checkSibling() of "+this.value);
if(this.children!=null){
String state = null;
int checked = 0;
int sub = 0;
int i;
TreeNode[] siblings = this.children;
for (i = 0; i < siblings.length; i++) {
TreeNode treeNode = siblings[i];
//System.out.println("\t"+treeNode.getValue()+" - "+treeNode.getState());
if(!treeNode.getState().equals("")){
if(treeNode.getState().equals("checked")){
checked++;
} else if(treeNode.getState().equals("sub")){
sub++;
}
}
}
if(checked == i){
state = "checked";
} else if(sub > 0 || checked > 0) {
state = "sub";
} else {
state = "";
}
//System.out.println("siblings: "+i+" (checked: "+checked+" sub: "+sub+") -> "+state);
return state;
} else {
return "";
}
}
public void setChildsChecked(TreeNode node){
//System.out.println("TreeNode -> setChildsChecked of "+node.getValue());
if(node.getChildren()!=null){
TreeNode[] children = node.getChildren();
for (int i = 0; i < children.length; i++) {
TreeNode treeNode = children[i];
treeNode.setState("checked");
setChildsChecked(treeNode);
}
}
}
public void setChildsUnchecked(TreeNode node){
//System.out.println("TreeNode -> setChildsUnchecked of "+node.getValue());
if(node.getChildren()!=null){
TreeNode[] children = node.getChildren();
for (int i = 0; i < children.length; i++) {
TreeNode treeNode = children[i];
treeNode.setState("");
setChildsUnchecked(treeNode);
}
}
}
public void setParentsState(TreeNode node){
System.out.println("TreeNode -> setParentsState of "+node.getValue());
node.setState(node.checkSibling());
if(node.getParent()!=null){
setParentsState(node.getParent());
}
}
public void actionListener(ActionEvent ae){
//System.out.println("TreeNode -> nodeListener fired by "+ae.getComponent().getId());
if(this.state == "checked"){
this.state = "";
setChildsUnchecked(this);
} else {
this.state = "checked";
setChildsChecked(this);
}
if(this.parent!=null){
setParentsState(this.parent);
}
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public TreeNode[] getChildren() {
return children;
}
public void setChildren(TreeNode[] children) {
this.children = children;
}
public TreeNode getParent() {
if(parent==null){
return null;
} else {
return parent;
}
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
[/code]
> <rich:tree> possible performance issue
> ---------------------------------------
>
> Key: RF-3569
> URL: http://jira.jboss.com/jira/browse/RF-3569
> Project: RichFaces
> Issue Type: Quality Risk
> Affects Versions: 3.2.0
> Reporter: martin bischoff
> Assigned To: Nick Belaevski
>
> i've got an quite simple tree with "just" 50 elements á 200 childs -> 10.000 nodes
> every node gots:
> - some little text
> - image for a checkbox via h:graphicImage
> - a4j:support for listenersupport at the image
> expanding/collapsing nodes and checking the checkboxes takes a lot of time...
> jprofiler tells me that most of the time is spend by domparsing. i dont know if i handle the tree as intended. here is some code:
> JSP
> [code]
> <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
> <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
> <html>
> <head>
> <title>tree</title>
> </head>
> <body>
> <f:view>
> <h:form>
> <a4j:loadStyle src="/res/button.css" />
> <a4j:loadStyle src="/res/tree/style.css" />
> <a4j:commandButton id="show_me" value="show childs" styleClass="normalButton">
> <a4j:ajaxListener type="controller.listener.ListenerBean" />
> </a4j:commandButton>
> <h:panelGrid columns="2">
> <h:outputLabel>
> <h:outputText value="infinite Tree extended"></h:outputText>
> <rich:tree componentState="#{treeBean.treeState}" id="infinite_Tree_expanded" style="width:300px" switchType="ajax" stateAdvisor="#{treeDemoStateAdvisor}">
>
> <rich:recursiveTreeNodesAdaptor roots="#{treeBean.rootNodes}" var="item" nodes="#{item.children}">
> <rich:treeNode nodeSelectListener="#{treeBean.processSelection}">
> <h:graphicImage value="/res/tree/chkb_#{item.state}.png">
> <a4j:support event="onclick" reRender="infinite_Tree_expanded" actionListener="#{item.actionListener}"/>
> </h:graphicImage>
> <h:outputText value="#{item.value} - #{item.state}"/>
> </rich:treeNode>
> </rich:recursiveTreeNodesAdaptor>
>
> </rich:tree>
> </h:outputLabel>
> </h:panelGrid>
> </h:form>
> </f:view>
> </body>
> </html>[/code]
> TreeBean:
> [code]package my_tree;
> import java.io.IOException;
> import java.io.InputStream;
> import java.util.Properties;
> import javax.faces.FacesException;
> import javax.faces.context.ExternalContext;
> import javax.faces.context.FacesContext;
> import javax.faces.event.AbortProcessingException;
> import org.richfaces.component.state.TreeState;
> import org.richfaces.event.NodeSelectedEvent;
> public class TreeBean {
> private TreeNode rootNode = null;
> private TreeNode[] rootNodes = null;
> private TreeState treeState;
> private static final String DATA_PATH = "/res/tree/simple-tree-data.properties";
> public TreeNode getRootNode() {
> if (rootNode == null) {
> loadTree();
> }
> return rootNode;
> }
> public void setRootNode(TreeNode rootNode) {
> this.rootNode = rootNode;
> }
> public TreeNode[] getRootNodes() {
> if (rootNodes == null) {
> rootNodes = this.getRootNode().getChildren();
> }
> return rootNodes;
> }
> public void setRootNodes(TreeNode[] rootNodes) {
> this.rootNodes = rootNodes;
> }
> public TreeState getTreeState() {
> return treeState;
> }
> public void setTreeState(TreeState treeState) {
> this.treeState = treeState;
> }
> private void addNodes(String path, TreeNode node, Properties properties) {
> boolean end = false;
> int counter = 1;
> while (!end) {
> String key = path != null ? path + '.' + counter : String
> .valueOf(counter);
> String value = properties.getProperty(key);
> if (value != null) {
> TreeNode newNode = new TreeNode(value);
> newNode.setParent(node);
> node.addNode(newNode);
> addNodes(key, newNode, properties);
> counter++;
> } else {
> end = true;
> }
> }
> }
> private void loadTree() {
> System.out.println("TreeBean -> loadTree()");
> FacesContext facesContext = FacesContext.getCurrentInstance();
> ExternalContext externalContext = facesContext.getExternalContext();
> InputStream dataStream = externalContext.getResourceAsStream(DATA_PATH);
> try {
> Properties properties = new Properties();
> properties.load(dataStream);
> rootNode = new TreeNode("root");
> addNodes(null, rootNode, properties);
> // manual tree extension
> TreeNode dummy = new TreeNode("Sichtlinie");
> int count = 0;
> for (int i = 1; i <= 50; i++) {
> count++;
> TreeNode node = new TreeNode("i" + i);
> for (int j = 1; j <= 200; j++) {
> count++;
> if (count % 1000 == 0) {
> System.out.println(count);
> }
> TreeNode child = new TreeNode("j" + j);
> child.setParent(node);
> node.addNode(child);
> }
> node.setParent(dummy);
> dummy.addNode(node);
> }
> rootNode.addNode(dummy);
> } catch (IOException e) {
> e.printStackTrace();
> throw new FacesException(e.getMessage(), e);
> } finally {
> if (dataStream != null) {
> try {
> dataStream.close();
> } catch (IOException e) {
> e.printStackTrace();
> externalContext.log(e.getMessage(), e);
> }
> }
> }
> }
> public void processSelection(NodeSelectedEvent arg0)
> throws AbortProcessingException {
> System.out.println("SimpleTreeBean -> processSelection fired by "
> + arg0.getComponent().getId());
> }[/code]
> TreeNode:
> [code]package my_tree;
> import javax.faces.event.ActionEvent;
> import org.richfaces.model.TreeNodeImpl;
> public class TreeNode{
> private String value;
> private String state;
> private TreeNode parent;
> private TreeNode[] children;
>
> public TreeNode(String value) {
> this.value = value;
> this.state = "";
> }
> public synchronized void addNode(TreeNode newChild) {
> System.out.println("addNode("+newChild.getValue()+")");
> if (this.children == null) {
> TreeNode[] merged = new TreeNode[1];
> merged[0] = newChild;
> this.children = merged;
> } else {
> TreeNode[] merged = new TreeNode[this.children.length + 1];
> int i;
> for (i = 0; i < this.children.length; i++) {
> merged[i] = this.children[i];
> }
> merged[merged.length - 1] = newChild;
> this.children = merged;
> }
> }
> public synchronized void addNodes(TreeNode[] newChildren) {
> System.out.println("addNodeS("+newChildren.length+")");
> TreeNode[] merged = new TreeNode[newChildren.length
> + this.children.length];
> int i;
> for (i = 0; i <= this.children.length; i++) {
> merged[i] = this.children[i];
> }
> for (int i2 = i; i2 <= newChildren.length + i; i2++) {
> merged[i2] = newChildren[i2];
> }
> this.children = merged;
> }
> public synchronized void removeNodes(TreeNode[] removeChildren) {
> TreeNode[] splitted = new TreeNode[this.children.length
> - removeChildren.length];
> int pos = 0;
> for (int i = 0; i <= this.children.length; i++) {
> boolean contains = false;
> for (int j = 0; j <= removeChildren.length; j++) {
> if (this.children[i] == removeChildren[j]) {
> contains = true;
> }
> }
> if (contains == false) {
> splitted[pos] = this.children[i];
> pos++;
> }
> }
> }
> public String checkSibling(){
> //System.out.println("checkSibling() of "+this.value);
> if(this.children!=null){
> String state = null;
> int checked = 0;
> int sub = 0;
> int i;
> TreeNode[] siblings = this.children;
> for (i = 0; i < siblings.length; i++) {
>
> TreeNode treeNode = siblings[i];
> //System.out.println("\t"+treeNode.getValue()+" - "+treeNode.getState());
> if(!treeNode.getState().equals("")){
> if(treeNode.getState().equals("checked")){
> checked++;
> } else if(treeNode.getState().equals("sub")){
> sub++;
> }
> }
>
> }
>
> if(checked == i){
> state = "checked";
> } else if(sub > 0 || checked > 0) {
> state = "sub";
> } else {
> state = "";
> }
> //System.out.println("siblings: "+i+" (checked: "+checked+" sub: "+sub+") -> "+state);
> return state;
> } else {
> return "";
> }
> }
>
> public void setChildsChecked(TreeNode node){
> //System.out.println("TreeNode -> setChildsChecked of "+node.getValue());
> if(node.getChildren()!=null){
> TreeNode[] children = node.getChildren();
> for (int i = 0; i < children.length; i++) {
> TreeNode treeNode = children[i];
> treeNode.setState("checked");
> setChildsChecked(treeNode);
> }
> }
> }
>
> public void setChildsUnchecked(TreeNode node){
> //System.out.println("TreeNode -> setChildsUnchecked of "+node.getValue());
> if(node.getChildren()!=null){
> TreeNode[] children = node.getChildren();
> for (int i = 0; i < children.length; i++) {
> TreeNode treeNode = children[i];
> treeNode.setState("");
> setChildsUnchecked(treeNode);
> }
> }
> }
> public void setParentsState(TreeNode node){
> System.out.println("TreeNode -> setParentsState of "+node.getValue());
> node.setState(node.checkSibling());
> if(node.getParent()!=null){
> setParentsState(node.getParent());
> }
> }
>
> public void actionListener(ActionEvent ae){
> //System.out.println("TreeNode -> nodeListener fired by "+ae.getComponent().getId());
> if(this.state == "checked"){
> this.state = "";
> setChildsUnchecked(this);
> } else {
> this.state = "checked";
> setChildsChecked(this);
> }
> if(this.parent!=null){
> setParentsState(this.parent);
> }
>
> }
>
> public String getValue() {
> return value;
> }
> public void setValue(String value) {
> this.value = value;
> }
> public TreeNode[] getChildren() {
> return children;
> }
> public void setChildren(TreeNode[] children) {
> this.children = children;
> }
>
>
> public TreeNode getParent() {
> if(parent==null){
> return null;
> } else {
> return parent;
> }
> }
> public void setParent(TreeNode parent) {
> this.parent = parent;
> }
> public String getState() {
> return state;
> }
> public void setState(String state) {
> this.state = state;
> }
> }
> [/code]
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the richfaces-issues
mailing list