/*******************************************************************************
* Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package com.w4t.dhtml;
import org.eclipse.rwt.internal.lifecycle.HtmlResponseWriter;
import com.w4t.Style;
import com.w4t.dhtml.event.*;
import com.w4t.dhtml.renderinfo.TreeNodeInfo;
import com.w4t.event.*;
import com.w4t.internal.adaptable.IRenderInfoAdapter;
import com.w4t.internal.adaptable.RenderInfoAdapter;
import com.w4t.types.WebColor;
import com.w4t.util.DefaultColorScheme;
/**
* <p>A Node for the TreeView.</p>
*/
public class TreeNode extends Node {
private static final ToggleLoadingListener TOGGLE_LOADING_LISTENER
= new ToggleLoadingListener();
private static final String ITEM_MARKED_FONT
= DefaultColorScheme.get( DefaultColorScheme.ITEM_MARKED_FONT );
private static final String ITEM_MARKED_BG
= DefaultColorScheme.get( DefaultColorScheme.ITEM_MARKED_BG );
private static final WebColor ITEM_MARKED_FONT_COLOR
= new WebColor( ITEM_MARKED_FONT );
private static final WebColor ITEM_MARKED_BG_COLOR
= new WebColor( ITEM_MARKED_BG );
private static final WebColor ITEM_FONT_COLOR
= new WebColor( DefaultColorScheme.get( DefaultColorScheme.ITEM_FONT ) );
/** <p>constant value for a mode of dynamic reloading of this treeNode.</p>
* <p><i>Never</i> loading means, that this TreeNode is always completely
* rendered.</p>
* <p>This is recommended for small trees which are not supposed to change
* at runtime.</p> */
public static final String DYNLOAD_NEVER = "never";
/** <p>constant value for a mode of dynamic reloading of this treeNode.</p>
* <p><i>Dynamic</i> loading means, that this TreeNode is not completely
* rendered, but only rendered on demand, if a certain (configurable )
* number of child nodes is exceeded (see setMinChildsDynLoad() ).</p> */
public static final String DYNLOAD_DYNAMIC = "dynamic";
/** <p>constant value for a mode of dynamic reloading of this treeNode.</p>
* <p><i>Always</i> loading means, that this TreeNode is not completely
* rendered, but only rendered on demand, independent of the number of
* child nodes.</p> */
public static final String DYNLOAD_ALWAYS = "always";
/** <p>the image set name that is set by default on tree nodes.</p> */
public static final String DEFAULT_IMAGE_SET
= "resources/images/treeview/modern/Modern";
/** helping list for render(): contains the html code for the hidden
* input fields which are used to store for every TreeNode the information
* whether it is expanded or collapsed. */
protected HtmlResponseWriter tbStateInfoFields;
/** <p>the number of child nodes and leaves added to this TreeNode.</p> */
protected int childCount = 0;
/** <p>if dynamic loading for the branch starting with this TreeNode is
* enabled, and this minimum number of children is exceeded, the branch is
* only rendered if it is to be shown.</p> */
protected String dynLoading = DYNLOAD_DYNAMIC;
/** <p>the minimal child node number for dynamic loading to this
* TreeNode.</p> */
protected int minChildsDynLoad = 50;
/** <p>the name (as pathname) of the images which are displayed as
* representation of this TreeNode in expanded and collapsed state.</p>
* <p>Images must be located at the specified path.</p>
* <p>Currently only gif images are supported.</p> */
protected String imageSetName = "";
/** tells, whether this TreeNode to expanded state, i.e. the childs
* on the level immediately below this node are visible. */
private boolean expanded = false;
/** helping variable for rendering: the String to be rendered into the layers
* for visibility. */
protected String expansion = "vis_hide";
/** the background color this TreeNode has when it is marked. */
private WebColor markedBgColor;
/** the color this TreeNode has when it is marked. */
private WebColor markedColor;
/** the css attribute encapsulation for this TreeNode */
private Style style;
/** tooltip displayed on mouseover with this TreeNode */
private String title = "";
private Object renderInfoAdapter;
/** creates a new instance of TreeNode */
public TreeNode() {
markedBgColor = ITEM_MARKED_BG_COLOR;
markedColor = ITEM_MARKED_FONT_COLOR;
tbStateInfoFields = new HtmlResponseWriter();
}
private void initStyle() {
style = new Style();
style.setTextDecoration( "none" );
style.setColor( ITEM_FONT_COLOR );
style.setWhiteSpace( "nowrap" );
}
/** <p>returns a copy of Node.</p> */
public Object clone() throws CloneNotSupportedException {
TreeNode result = ( TreeNode )super.clone();
if( style != null ) {
result.initStyle();
}
return result;
}
private TreeNodeInfo doCreateInfo() {
this.removeWebTreeNodeExpandedListener( TOGGLE_LOADING_LISTENER );
boolean marked = tdItems.isMarked( itemID );
TreeNodeShift treeNodeShift = this.findRoot().getTreeNodeShift();
return new TreeNodeInfo( tbStateInfoFields,
nodeList,
leafList,
this,
marked,
TOGGLE_LOADING_LISTENER,
expansion,
treeNodeShift );
}
public Object getAdapter( final Class adapter ) {
Object result;
if( adapter == IRenderInfoAdapter.class ) {
result = getRenderInfoAdapter();
} else {
result = super.getAdapter( adapter );
}
return result;
}
private Object getRenderInfoAdapter() {
if( renderInfoAdapter == null ) {
renderInfoAdapter = new RenderInfoAdapter() {
private TreeNodeInfo renderInfo;
public Object getInfo() {
return renderInfo;
}
public void createInfo() {
renderInfo = doCreateInfo();
}
};
}
return renderInfoAdapter;
}
/** <p>adds the specified WebTreeNodeExpandedListener to this
* TreeNode.</p> */
public void addWebTreeNodeExpandedListener(
final WebTreeNodeExpandedListener listener )
{
WebTreeNodeExpandedEvent.addListener( this, listener );
}
/** <p>Removes the specified <code>WebTreeNodeExpandedListener</code> from
* this TreeNode.</p>
* <p>This method performs no function, nor does it throw an exception, if
* the given <code>listener</code> was not previously added to this component.
* If listener is <code>null</code>, no exception is thrown and no action
* is performed.</p>
* @param listener the <code>WebTreeNodeExpandedListener</code> to be removed.
*/
public void removeWebTreeNodeExpandedListener(
final WebTreeNodeExpandedListener listener )
{
WebTreeNodeExpandedEvent.removeListener( this, listener );
}
/** <p>Adds the specified WebTreeNodeCollapsedListener to this
* TreeNode.</p> */
public void addWebTreeNodeCollapsedListener(
final WebTreeNodeCollapsedListener listener )
{
WebTreeNodeCollapsedEvent.addListener( this, listener );
}
/**
* <p>Removes the specified <code>WebTreeNodeCollapsedListener</code> from
* this TreeNode.</p>
* <p>This method performs no function, nor does it throw an exception, if
* the given <code>listener</code> was not previously added to this component.
* If listener is <code>null</code>, no exception is thrown and no action
* is performed.</p>
* @param listener the <code>WebTreeNodeCollapsedListener</code> to be
* removed.
* */
public void removeWebTreeNodeCollapsedListener(
final WebTreeNodeCollapsedListener listener )
{
WebTreeNodeCollapsedEvent.removeListener( this, listener );
}
/** <p>adds the specified WebTreeNodeExpandedListener to this
* TreeNode and recursively to all of its child nodes.</p> */
protected void addWebTreeNodeExpandedListenerRecursively(
final WebTreeNodeExpandedListener listener )
{
this.addWebTreeNodeExpandedListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.addWebTreeNodeExpandedListenerRecursively( listener );
}
}
/** <p>removes the specified WebTreeNodeExpandedListener from
* this TreeNode and from all of its child nodes.</p> */
protected void removeWebTreeNodeExpandedListenerRecursively(
final WebTreeNodeExpandedListener listener )
{
this.removeWebTreeNodeExpandedListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.removeWebTreeNodeExpandedListenerRecursively( listener );
}
}
/** <p>Adds the specified WebTreeNodeCollapsedListener to this
* TreeNode and to all of its child nodes.</p> */
protected void addWebTreeNodeCollapsedListenerRecursively(
final WebTreeNodeCollapsedListener listener )
{
this.addWebTreeNodeCollapsedListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.addWebTreeNodeCollapsedListenerRecursively( listener );
}
}
/** <p>Removes the specified WebTreeNodeCollapsedListener from
* this TreeNode and from all of its child nodes.</p> */
protected void removeWebTreeNodeCollapsedListenerRecursively(
final WebTreeNodeCollapsedListener listener )
{
this.removeWebTreeNodeCollapsedListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.removeWebTreeNodeCollapsedListenerRecursively( listener );
}
}
/** <p>Adds the specified DragDropListener to this TreeNode.</p> */
public void addDragDropListener( final DragDropListener listener ) {
DragDropEvent.addListener( this, listener );
}
/**
* <p>Removes the specified <code>DragDropListener</code> from this TreeNode.
* </p>
* <p>This method performs no function, nor does it throw an exception, if
* the given <code>listener</code> was not previously added to this component.
* If listener is <code>null</code>, no exception is thrown and no action
* is performed.</p>
* @param listener the <code>DragDropListener</code> to be removed.
*/
public void removeDragDropListener( final DragDropListener listener ) {
DragDropEvent.removeListener( this, listener );
}
/**
* <p>Adds the specified <code>DoubeClickListener</code> to receive double-
* click events from this item. These events occur when a user double-clicks
* this item.</p>
* @param listener the <code>DoubleClickListener</code> to be added. Must
* not be <code>null</code>.
*/
public void addDoubleClickListener( final DoubleClickListener listener ) {
DoubleClickEvent.addListener( this, listener );
}
/**
* <p>Removes the specified <code>DoubleClickListener</code> so that it no
* longer receives double-click events from this item.</p>
* <p>This method performs no function, nor does it throw an exception, if
* the given <code>listener</code> was not previously added to this component.
* If listener is <code>null</code>, no exception is thrown and no action
* is performed.</p>
* @param listener the <code>DoubleClickListener</code> to be removed.
*/
public void removeDoubleClickListener( final DoubleClickListener listener ) {
DoubleClickEvent.removeListener( this , listener );
}
/** <p>Adds the specified <code>DoubleClickListener</code> to this TreeNode
* and to all of its child nodes.</p> */
protected void addDoubleClickListenerRecursively(
final DoubleClickListener listener )
{
DoubleClickEvent.addListener( this, listener );
for( int i = 0; i < nodeList.size(); i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.addDoubleClickListenerRecursively( listener );
}
for( int i = 0; i < leafList.size(); i++ ) {
TreeLeaf leaf = ( TreeLeaf )leafList.get( i );
leaf.addDoubleClickListener( listener );
}
}
/** <p>Removes the specified <code>DoubleClickListener</code> from
* this TreeNode and from all of its child nodes.</p> */
protected void removeDoubleClickListenerRecursively(
final DoubleClickListener listener )
{
DoubleClickEvent.removeListener( this, listener );
for( int i = 0; i < nodeList.size(); i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.removeDoubleClickListenerRecursively( listener );
}
for( int i = 0; i < leafList.size(); i++ ) {
TreeLeaf leaf = ( TreeLeaf )leafList.get( i );
leaf.removeDoubleClickListener( listener );
}
}
/** <p>Adds the specified DragDropListener to this TreeNode and to
* all of its child nodes.</p> */
protected void addDragDropListenerRecursively(
final DragDropListener listener )
{
this.addDragDropListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.addDragDropListenerRecursively( listener );
}
}
/** <p>Removes the specified DragDropListener from this TreeNode and
* from all of its child nodes.</p> */
protected void removeDragDropListenerRecursively(
final DragDropListener listener )
{
this.removeDragDropListener( listener );
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.removeDragDropListenerRecursively( listener );
}
}
/** <p>Sets this TreeNode to expanded state, i.e. the childs on the level
* immediately below this node are visible.</p> */
public void setExpanded( final boolean expanded ) {
this.expanded = expanded;
if( expanded ) {
// set all parents up to root to expanded = true
if( parentNode != null ) {
( ( TreeNode )parentNode ).setExpanded( true );
}
} else {
// set all children to expanded = false
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode child = ( TreeNode )nodeList.get( i );
child.setExpanded( false );
}
}
expansion = expanded ? "vis_show" : "vis_hide";
}
/** <p>returns, whether this TreeNode to expanded state, i.e. the childs
* on the level immediately below this node are visible.</p> */
public boolean isExpanded() {
return expanded;
}
/** <p>Sets the specified number as minimal child node number for
* dynamic loading to this TreeNode.</p>
* <p>Note: the minimal child node number for dynamic loading can be
* set on the TreeView, to which this TreeNode is added; this will apply it
* to all TreeNodes added to the TreeView. If you set the number on this
* TreeNode, it applies only to this TreeNode.</p> */
public void setMinChildsDynLoad( final int minChildsDynLoad ) {
this.minChildsDynLoad = minChildsDynLoad;
}
/** <p>Returns the minimal child node number for dynamic loading
* which is set on this TreeNode.</p>
* <p>Note: the minimal child node number for dynamic loading can be
* set on the TreeView, to which this TreeNode is added; this will apply it
* to all TreeNodes added to the TreeView. If you set the number on this
* TreeNode only, it applies only to this TreeNode.</p> */
public int getMinChildsDynLoad( ) {
return this.minChildsDynLoad;
}
/** <p>Sets the specified dynamic loading mode identifier for dynamic
* loading to this TreeNode. This must be one of TreeNode.DYNLOAD_NEVER,
* TreeNode.DYNLOAD_ALWAYS and TreeNode.DYNLOAD_DYNAMIC.</p>
* <p>Note: the dynamic loading mode can be set on the TreeView, to which
* this TreeNode is added; this will apply it to all TreeNodes added to
* the TreeView. If you set the mode on this TreeNode, it applies
* only to this TreeNode.</p> */
public void setDynLoading( final String dynLoading ) {
if( !dynLoading.equals( DYNLOAD_NEVER )
&& !dynLoading.equals( DYNLOAD_ALWAYS )
&& !dynLoading.equals( DYNLOAD_DYNAMIC ) )
{
String msg = "No valid paramater for dynamic loading.";
throw new IllegalArgumentException( msg );
}
this.dynLoading = dynLoading;
}
/** <p>Returns the dynamic loading mode identifier for dynamic
* loading to this TreeNode. This is one of TreeNode.DYNLOAD_NEVER,
* TreeNode.DYNLOAD_ALWAYS and TreeNode.DYNLOAD_DYNAMIC.</p>
* <p>Note: the dynamic loading mode can be set on the TreeView, to which
* this TreeNode is added; this will apply it to all TreeNodes added to
* the TreeView. If you set the mode on this TreeNode, it applies
* only to this TreeNode.</p> */
public String getDynLoading( ) {
return this.dynLoading;
}
/** <p>Returns the topmost parent node of this TreeNode, i.e. the parent or
* parent of a parent of this TreeNode, which has no more parent above.</p>
* <p>Note that the return value of this is not necessarily of type
* TreeView.</p>
* <p>If there is no parent node above this TreeNode, a reference to this
* TreeNode itself is returned.</p> */
public TreeNode getRootNode() {
TreeNode result = this;
TreeNode temp = this;
while( temp != null ) {
result = temp;
temp = ( TreeNode )result.getParentNode();
}
return result;
}
/** <p>Determines and returns the count of children which are added to
* this TreeNode (recursively, i.e. all children and children of
* children etc. are counted).</p> */
public int getChildCount() {
this.childCount = 0;
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode child = ( TreeNode )nodeList.get( i );
this.childCount += child.getChildCount() + 1;
}
this.childCount += leafList.size();
return this.childCount;
}
// inherited and overriden methods
//////////////////////////////////
/**
* <p>Adds the specified item as child to this TreeNode.</p>
* <p>Note that all event listeners which are set to the root node of this
* TreeNode (which is either a {@link org.eclipse.rwt.dhtml.TreeView TreeView} or the
* root node of a branch of TreeNodes) are added to item. This applies
* also to dynloading settings (see {@link #setMinChildsDynLoad(int)
* setMinChildsDynLoad(int)} and {@link #setDynLoading(String)
* setDynLoading(String)}).If you want to set a special dynloading for
* item, apply it after you added it.</p> */
public void addItem( final Item item ) {
super.addItem( item );
TreeView root = findRoot();
if( root != null ) {
// must add the action listener of root, but cannot use
// addWebActionListener of root, which is recursive
Object[] actionListeners = WebActionEvent.getListeners( root );
for( int i = 0; i < actionListeners.length; i++ ) {
item.addWebActionListener( ( WebActionListener )actionListeners[ i ] );
}
Object[] dblClickListeners = DoubleClickEvent.getListeners( root );
for( int i = 0; i < dblClickListeners.length; i++ ) {
DoubleClickListener dblClickListener
= ( DoubleClickListener )dblClickListeners[ i ];
DoubleClickEvent.addListener( item, dblClickListener );
}
Object[] renderListeners = WebRenderEvent.getListeners( root );
for( int i = 0; i < renderListeners.length; i++ ) {
item.addWebRenderListener( ( WebRenderListener )renderListeners[ i ] );
}
// with TreeNode specific listeners dito
if( item instanceof TreeNode ) {
TreeNode treeNode = ( TreeNode )item;
Object[] dragDropListeners = DragDropEvent.getListeners( root );
for( int i = 0; i < dragDropListeners.length; i++ ) {
DragDropListener dragDropListener
= ( DragDropListener )dragDropListeners[ i ];
treeNode.addDragDropListener( dragDropListener );
}
Object[] expandedListeners
= WebTreeNodeExpandedEvent.getListeners( root );
for( int i = 0; i < expandedListeners.length; i++ ) {
WebTreeNodeExpandedListener expandedListener
= ( WebTreeNodeExpandedListener )expandedListeners[ i ];
treeNode.addWebTreeNodeExpandedListener( expandedListener );
}
Object[] collapsedListeners
= WebTreeNodeCollapsedEvent.getListeners( root );
for( int i = 0; i < collapsedListeners.length; i++ ) {
WebTreeNodeCollapsedListener collapsedListener
= ( WebTreeNodeCollapsedListener )collapsedListeners[ i ];
treeNode.addWebTreeNodeCollapsedListener( collapsedListener );
}
treeNode.setDynLoading( this.getDynLoading() );
treeNode.setMinChildsDynLoad( this.getMinChildsDynLoad() );
}
}
}
/** <p>Removes the specified item from this TreeNode, removing also all
* listeners from it which were set to it from the root of this tree.</p>
*/
public void removeItem( final Item item ) {
super.removeItem( item );
TreeView root = findRoot();
if( root != null ) {
// must remove the action listener of root, but cannot use
// removeWebActionListener of root, which is recursive
Object[] actionListeners = WebActionEvent.getListeners( root );
for( int i = 0; i < actionListeners.length; i++ ) {
WebActionListener actionListener
= ( WebActionListener )actionListeners[ i ];
item.removeWebActionListener( actionListener );
}
Object[] dblClickListeners = DoubleClickEvent.getListeners( root );
for( int i = 0; i < dblClickListeners.length; i++ ) {
DoubleClickListener dblClickListener
= ( DoubleClickListener )dblClickListeners[ i ];
DoubleClickEvent.removeListener( item, dblClickListener );
}
Object[] renderListeners = WebRenderEvent.getListeners( root );
for( int i = 0; i < renderListeners.length; i++ ) {
WebRenderListener renderListener
= ( WebRenderListener )renderListeners[ i ];
item.removeWebRenderListener( renderListener );
}
// with TreeNode specific listeners dito
if( item instanceof TreeNode ) {
TreeNode treeNode = ( TreeNode )item;
Object[] dragDropListeners = DragDropEvent.getListeners( root );
for( int i = 0; i < dragDropListeners.length; i++ ) {
DragDropListener dragDropListener
= ( DragDropListener )dragDropListeners[ i ];
treeNode.removeDragDropListener( dragDropListener );
}
Object[] expandedListeners
= WebTreeNodeExpandedEvent.getListeners( root );
for( int i = 0; i < expandedListeners.length; i++ ) {
WebTreeNodeExpandedListener expandedListener
= ( WebTreeNodeExpandedListener )expandedListeners[ i ];
treeNode.removeWebTreeNodeExpandedListener( expandedListener );
}
Object[] collapsedListeners
= WebTreeNodeCollapsedEvent.getListeners( root );
for( int i = 0; i < collapsedListeners.length; i++ ) {
WebTreeNodeCollapsedListener collapsedListener
= ( WebTreeNodeCollapsedListener )collapsedListeners[ i ];
treeNode.removeWebTreeNodeCollapsedListener( collapsedListener );
}
}
}
}
// attribute getters and setters
////////////////////////////////
/** Sets the tooltip displayed on mouseover with this TreeNode */
public void setTitle( final String title ) {
this.title = title;
}
/** Returns the tooltip displayed on mouseover with this TreeNode */
public String getTitle() {
return title;
}
/** Sets the css attribute encapsulation for this TreeNode */
public void setStyle( final Style style ) {
this.style = style;
}
/** Returns the css attribute encapsulation for this TreeNode */
public Style getStyle() {
if( style == null ) {
initStyle();
}
return style;
}
/** <p>Sets the color this TreeNode has when it is marked.</p> */
public void setMarkedColor( final WebColor markedColor ) {
this.markedColor = markedColor;
}
/** <p>Returns the color this TreeNode has when it is marked.</p> */
public WebColor getMarkedColor() {
return markedColor;
}
/** <p>Sets the background color this TreeNode has when it is marked.</p> */
public void setMarkedBgColor( final WebColor markedBgColor ) {
this.markedBgColor = markedBgColor;
}
/** <p>Returns the background color this TreeNode has when it is
* marked.</p> */
public WebColor getMarkedBgColor() {
return markedBgColor;
}
/** <p>Sets the name (as pathname) of the images which are displayed as
* representation of this TreeNode in expanded and collapsed state.</p>
* <p>If no imageset is set on this TreeNode, the imageSetName of the
* parent node is used instead.</p>
* <p>Currently only gif images are supported.</p> */
public void setImageSetName( final String imageSetName ) {
this.imageSetName = imageSetName;
}
/** <p>Returns the name (as pathname) of the images which are displayed as
* representation of this TreeNode in expanded and collapsed state.</p>
* <p>If no imageset is set on this TreeNode, the imageSetName of the
* parent node is used instead.</p>
* <p>Currently only gif images are supported.</p> */
public String getImageSetName() {
String result = imageSetName;
if( result.equals( "" ) && getParentNode() != null ) {
result = ( ( TreeNode )getParentNode() ).getImageSetName();
}
return result;
}
/** <p>Returns, whether this TreeNode is enabled (reacts on user input)
* or not. A WebComponent is also not enabled if it is added to a
* WebContainer and the WebContainer to which it is added is
* disabled.</p> */
public boolean isEnabled() {
boolean result = super.isEnabled();
if( getParentNode() != null ) {
TreeNode parentNode = ( TreeNode )getParentNode();
result = result && parentNode.isEnabled();
}
return result;
}
/** helping method: sets the String to be rendered into the layers
* for visibility. */
public void setExpansion( final String expansion ) {
this.expansion = expansion;
this.expanded = expansion.equals( "vis_show" ) ? true : false;
}
// package private helping methods
//////////////////////////////////
/** helping method for rendering: adds html code for the hidden input
* fields which are used to store for every TreeNode the information
* whether it is expanded or collapsed. */
public void addStateInfo( final HtmlResponseWriter stateInfo ) {
tbStateInfoFields.append( stateInfo );
}
/** helping method for rendering: adds html code for the hidden input
* fields which are used to store for every TreeNode the information
* whether it is expanded or collapsed. */
public void addStateInfo( final String stateInfo ) {
tbStateInfoFields.append( stateInfo );
}
/** helping method; returns the root node of the tree to which this
* TreeNode is added, if any, or null else. */
TreeView findRoot() {
Node result = this;
while( result != null && !( result instanceof TreeView ) ) {
result = result.getParentNode();
}
// cast is valid here, for result can be either null or instanceof TreeView
return ( TreeView )result;
}
/** sets the specified number as minimal child node number for
* dynamic loading to this TreeNode and to all of its child nodes. */
void setMinChildsDynLoadRecursively( final int minChildsDynLoad ) {
this.minChildsDynLoad = minChildsDynLoad;
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.setMinChildsDynLoadRecursively( minChildsDynLoad );
}
}
/** sets the specified mode of dynamic loading to this TreeNode and
* to all of its child nodes. */
void setDynLoadingRecursively( final String dynLoading ) {
if( !dynLoading.equals( DYNLOAD_NEVER )
&& !dynLoading.equals( DYNLOAD_ALWAYS )
&& !dynLoading.equals( DYNLOAD_DYNAMIC ) )
{
String msg = "No valid paramater for dynamic loading.";
throw new IllegalArgumentException( msg );
}
this.dynLoading = dynLoading;
int size = nodeList.size();
for( int i = 0; i < size; i++ ) {
TreeNode childNode = ( TreeNode )nodeList.get ( i );
childNode.setDynLoadingRecursively( dynLoading );
}
}
// inner classes
////////////////
/** a helping listener class which just causes a reload on the
* branch below this TreeNode. */
static class ToggleLoadingListener implements WebTreeNodeExpandedListener {
public void webTreeNodeExpanded( final WebTreeNodeExpandedEvent evt ) {
// there is nothing to do, since the event itself causes the
// tree to be rendered again
}
}
}