All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.gluebooster.java.booster.basic.container.BeanTreeNode Maven / Gradle / Ivy

Go to download

Basic classes to support the development of applications. There should be as few dependencies on other frameworks as possible.

The newest version!
package net.sf.gluebooster.java.booster.basic.container;

import java.beans.PropertyDescriptor;
import java.util.Collection;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;

import net.sf.gluebooster.java.booster.essentials.eventsCommands.Callable;
import net.sf.gluebooster.java.booster.essentials.meta.HasName;
import net.sf.gluebooster.java.booster.essentials.utils.ReflectionBoostUtils;

/**
 * A bean as tree node. The properties are the children. If the bean is a
 * collection then it has an additional child that contains the elements of the
 * collection
 * 
 * The value of a primitive bean (String, Boolean, ..) is the user object
 * 
 * @defaultParamText bean the inspected bean (may be null)
 * @defaultParamText initChildrenRecursionDepth the recursion depth to which the
 *                   initialization (child tree) should be done.
 * @author CBauer
 * 
 */
public class BeanTreeNode extends DefaultMutableTreeNode {


	/**
	 * If this node represents a property this is its description.
	 */
	private PropertyDescriptor property;

	/**
	 * Should properties be the children of this node?
	 */
	private boolean usePropertiesAsChildren = true;

	/**
	 * If this bean is a collection then this flag determines whether the
	 * elements should be children.
	 */
	private boolean useElementsAsChildren = false;

	public BeanTreeNode(Object bean) throws Exception {
		userObject = bean;
		initChildren(1, false);
	}

	/**
	 * 
	 * @param parentBean
	 *            the bean which property is to be evaluated to get the bean
	 */
	private BeanTreeNode(Object parentBean, PropertyDescriptor property,
			Object bean,
			int initChildrenRecursionDepth) throws Exception {

		this.property = property;
		if (bean != null) {
			userObject = bean;
		} else if (parentBean != null && property != null) {
			userObject = ReflectionBoostUtils.getProperty(parentBean,
					property.getName());
		}

		initChildren(initChildrenRecursionDepth, false);
	}


	/**
	 * Computes the child nodes.
	 * 
	 * @param clearBefore
	 *            should the children be removed before the computation
	 */
	private void initChildren(int initChildrenRecursionDepth,
			boolean clearBefore)
			throws Exception {


		if (userObject != null && initChildrenRecursionDepth >= 0) {

			if (clearBefore) {

				children = null;
			}

			if (children == null) {
				// create children

				children = new Vector();
				if (usePropertiesAsChildren){
					for (PropertyDescriptor property : ReflectionBoostUtils
							.getPropertyDescriptors(userObject)) {
	
						String propertyName = property.getName();
						if (property.getReadMethod() != null
								&& property.getWriteMethod() != null) {
							add(new BeanTreeNode(userObject, property, null,
									initChildrenRecursionDepth - 1));
						}
					}
				}

				if ((userObject instanceof Collection)) {
					if (useElementsAsChildren) {
						for (Object child : ((Collection) userObject)) {
							add(new BeanTreeNode(userObject, null, child, 2));
						}
					} else {
						PropertyDescriptor childProperty = new PropertyDescriptor(
								"userObject", DefaultMutableTreeNode.class);// default
																			// property
																			// so
																			// that
						// the constructor does not
						// fail
						childProperty.setName("elements");

						BeanTreeNode child = new BeanTreeNode(userObject,
								childProperty, userObject,
								initChildrenRecursionDepth - 1);
						child.usePropertiesAsChildren = false;
						child.useElementsAsChildren = true;
						add(child);
					}
				}



			} else {
				// update children
				for (Object child : children) {
					((BeanTreeNode) child).initChildren(
							initChildrenRecursionDepth - 1,
							false);
				}
			}

		}
	}

	@Override
	public String toString() {
		try {
			initChildren(1, false);

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		if (property == null) {
			if (userObject == null)
				return "null";
			else {
				String result = userObject.getClass().getSimpleName();
				if (userObject instanceof HasName) {
					result += ": " + ((HasName) userObject).getName();
				}
				return result;
			}
		} else if (isBasicProperty()) {
			return property.getName() + ": " + userObject;
		} else {
			return property.getName();
		}

	}

	/**
	 * Basic properties are the properties that may be modified.
	 * 
	 * @return true if the property is a string. Other properties can not be
	 *         modified yet.
	 */
	private boolean isBasicProperty() {
		Class type = property.getPropertyType();
		return String.class.equals(type);
		// return type.isPrimitive() || Boolean.class.equals(type)
		// || String.class.equals(type) || Integer.class.equals(type)
		// || Long.class.equals(type);
	}

	@Override
	public void setUserObject(Object newUserObject) {
		String message = null;
		try {
			if (isBasicProperty()) {
				Object parentBean = ((BeanTreeNode) getParent())
						.getUserObject();

				property.getWriteMethod().invoke(
						parentBean,
						ReflectionBoostUtils.convertTo(newUserObject,
								property.getPropertyType()));
				userObject = property.getReadMethod().invoke(parentBean);
			} else {
				message = "Only basic properties are editable";
			}
		} catch (Exception ex) {
			message = ex.getMessage();
		}

		if (message != null)
			JOptionPane.showMessageDialog(null, message);

	}

	public boolean isUsePropertiesAsChildren() {
		return usePropertiesAsChildren;
	}

	public boolean isUseElementsAsChildren() {
		return useElementsAsChildren;
	}

	@Override
	public void remove(int childIndex) {
		// first do the removal in the bean
		BeanTreeNode child = (BeanTreeNode) getChildAt(childIndex);
		if (useElementsAsChildren) {
			((Collection) userObject).remove(child.getUserObject());
		} else
			throw new IllegalStateException("Must not remove");

		// then remove the child node
		super.remove(childIndex);
	}

	/**
	 * Creates a new child from of the userObject. The useElementsAsChildren-flag must be set and the userObject must be an callable.
	 * 
	 * REMARK: a change to callable must be synchronized with the SimpleBeanEditor
	 * 
	 * @throws Exception
	 */
	public void addNewChild() throws Exception {
		if (useElementsAsChildren) {
			Object child;
			if (userObject instanceof Callable) {
				child = ((Callable) userObject).call();
			} else {
				throw new IllegalStateException("No callable");
			}
			((Collection) userObject).add(child);
			initChildren(1, true);

		} else
			throw new IllegalStateException("Must not add");
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy