javax.media.j3d.OrderedGroup Maven / Gradle / Ivy
/*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package javax.media.j3d;
import java.util.Arrays;
/**
* The OrderedGroup node is a Group that ensures its children render
* in a specified order. In addition to the list of children
* inherited from the base Group class, OrderedGroup defines an
* integer array of child indices that specify the order in which its
* children are rendered. This provides a level of indirection in
* determining the rendering order of its children. By default, the
* child index order array is null, and the children are rendered in
* increasing index order.
*
*
* When the child index order array is non-null, it must be the same
* length as the number of children. Every entry in the array must
* have a unique value between 0 and numChildren-1
(i.e.,
* there must be no duplicate values and no missing indices). The
* order that the child indices appear in the child index order array
* determines the order in which the children are rendered. The child
* at childIndexOrder[0]
is rendered first, followed by
* childIndexOrder[1]
, and so on, with the child at
* childIndexOrder[numChildren-1]
rendered
* last.
*
*
* The child index order array only affects rendering. List
* operations that refer to a child by index, such as getChild(index),
* will not be altered by the entries in this array. They will get,
* enumerate, add, remove, etc., the children based on the actual
* index in the group node. However, some of the list operations,
* such as addChild, removeChild, etc., will update the child index
* order array as a result of their operation. For example,
* removeChild will remove the entry in the child index order array
* corresponding to the removed child's index and adjust the remaining
* entries accordingly. See the documentation for these methods for
* more details.
*/
public class OrderedGroup extends Group {
private boolean checkArr[] = null;
/**
* Specifies that this OrderedGroup node
* allows reading its child index order information.
*
* @since Java 3D 1.3
*/
public static final int ALLOW_CHILD_INDEX_ORDER_READ =
CapabilityBits.ORDERED_GROUP_ALLOW_CHILD_INDEX_ORDER_READ;
/**
* Specifies that this OrderedGroup node
* allows writing its child index order information.
*
* @since Java 3D 1.3
*/
public static final int ALLOW_CHILD_INDEX_ORDER_WRITE =
CapabilityBits.ORDERED_GROUP_ALLOW_CHILD_INDEX_ORDER_WRITE;
// Array for setting default read capabilities
private static final int[] readCapabilities = {
ALLOW_CHILD_INDEX_ORDER_READ
};
/**
* Constructs and initializes a new OrderedGroup node object.
* The childIndexOrder array is initialized to null, meaning
* that its children are rendered in increasing index order.
*/
public OrderedGroup() {
// set default read capabilities
setDefaultReadCapabilities(readCapabilities);
}
/**
* Sets the childIndexOrder array. If the specified array is
* null, this node's childIndexOrder array is set to null. Its
* children will then be rendered in increasing index order. If
* the specified array is not null, the entire array is copied to
* this node's childIndexOrder array. In this case, the length of
* the array must be equal to the number of children in this
* group, and every entry in the array must have a unique value
* between 0 and numChildren-1
(i.e., there must be
* no duplicate values and no missing indices).
*
* @param childIndexOrder the array that is copied into this
* node's child index order array; this can be null
*
* @exception IllegalArgumentException if the specified array is
* non-null and any of the following are true:
*
* childIndexOrder.length != numChildren
;
* childIndexOrder[
i] < 0
,
* for i in [0, numChildren-1]
;
* childIndexOrder[
i] >= numChildren
,
* for i in [0, numChildren-1]
;
* childIndexOrder[
i] ==
* childIndexOrder[
j]
,
* for i,j in [0, numChildren-1]
,
* i !=
j;
*
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void setChildIndexOrder(int[] childIndexOrder) {
verifyChildIndexOrderArray(childIndexOrder, 0);
((OrderedGroupRetained)retained).setChildIndexOrder(childIndexOrder);
}
/**
* Retrieves the current childIndexOrder array.
*
* @return a copy of this node's childIndexOrder array; this
* can be null.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public int[] getChildIndexOrder() {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_CHILD_INDEX_ORDER_READ))
throw new
CapabilityNotSetException(J3dI18N.getString("OrderedGroup5"));
return ((OrderedGroupRetained)this.retained).getChildIndexOrder();
}
/**
* Appends the specified child node to this group node's list of
* children, and sets the child index order array to the specified
* array. If the specified array is null, this node's
* childIndexOrder array is set to null. Its children will then
* be rendered in increasing index order. If the specified array
* is not null, the entire array is copied to this node's
* childIndexOrder array. In this case, the length of the array
* must be equal to the number of children in this group after the
* new child has been added, and every entry in the array must
* have a unique value between 0 and numChildren-1
* (i.e., there must be no duplicate values and no missing
* indices).
*
* @param child the child to add to this node's list of children
*
* @param childIndexOrder the array that is copied into this
* node's child index order array; this can be null
*
* @exception CapabilityNotSetException if the appropriate capability is
* not set and this group node is part of live or compiled scene graph
*
* @exception RestrictedAccessException if this group node is part
* of live
* or compiled scene graph and the child node being added is not
* a BranchGroup node
*
* @exception MultipleParentException if child
has already
* been added as a child of another group node.
*
* @exception IllegalArgumentException if the specified array is
* non-null and any of the following are true:
*
* childIndexOrder.length != numChildren
;
* childIndexOrder[
i] < 0
,
* for i in [0, numChildren-1]
;
* childIndexOrder[
i] >= numChildren
,
* for i in [0, numChildren-1]
;
* childIndexOrder[
i] ==
* childIndexOrder[
j]
,
* for i,j in [0, numChildren-1]
,
* i !=
j;
*
*
* @since Java 3D 1.3
*/
public void addChild(Node child, int[] childIndexOrder) {
verifyAddStates(child);
verifyChildIndexOrderArray(childIndexOrder, 1);
((OrderedGroupRetained)retained).addChild(child, childIndexOrder);
}
// Overridden methods from Group
/**
* Appends the specified child node to this group node's list of children.
*
*
* If the current child index order array is non-null, the array
* is increased in size by one element, and a new element
* containing the index of the new child is added to the end of
* the array. Thus, this new child will be rendered last.
*
* @param child the child to add to this node's list of children
* @exception CapabilityNotSetException if the appropriate capability is
* not set and this group node is part of live or compiled scene graph
* @exception RestrictedAccessException if this group node is part
* of live
* or compiled scene graph and the child node being added is not
* a BranchGroup node
* @exception MultipleParentException if child
has already
* been added as a child of another group node.
*
* @since Java 3D 1.3
*/
@Override
public void addChild(Node child) {
// Just call super -- the extra work is done by the retained class
super.addChild(child);
}
/**
* Inserts the specified child node in this group node's list of
* children at the specified index.
* This method is only supported when the child index order array
* is null.
*
* @param child the new child
* @param index at which location to insert. The index
* must be a value
* greater than or equal to 0 and less than or equal to
* numChildren()
.
* @exception CapabilityNotSetException if the appropriate capability is
* not set and this group node is part of live or compiled scene graph
* @exception RestrictedAccessException if this group node is part of
* live
* or compiled scene graph and the child node being inserted is not
* a BranchGroup node
* @exception MultipleParentException if child
has already
* been added as a child of another group node.
* @exception IndexOutOfBoundsException if index
is invalid.
* @exception IllegalStateException if the childIndexOrder array is
* not null.
*
* @since Java 3D 1.3
*/
@Override
public void insertChild(Node child, int index) {
if (((OrderedGroupRetained)retained).userChildIndexOrder != null) {
throw new IllegalStateException(J3dI18N.getString("OrderedGroup6"));
}
// Just call super -- the extra work is done by the retained class
super.insertChild(child, index);
}
/**
* Removes the child node at the specified index from this group node's
* list of children.
*
*
* If the current child index order array is non-null, the element
* containing the removed child's index will be removed from the
* child index order array, and the array will be reduced in size
* by one element. If the child removed was not the last child in
* the Group, the values of the child index order array will be
* updated to reflect the indices that were renumbered. More
* formally, each child whose index in the Group node was greater
* than the removed element (before removal) will have its index
* decremented by one.
*
* @param index which child to remove. The index
* must be a value
* greater than or equal to 0 and less than numChildren()
.
* @exception CapabilityNotSetException if the appropriate capability is
* not set and this group node is part of live or compiled scene graph
* @exception RestrictedAccessException if this group node is part of
* live or compiled scene graph and the child node being removed is not
* a BranchGroup node
* @exception IndexOutOfBoundsException if index
is invalid.
*
* @since Java 3D 1.3
*/
@Override
public void removeChild(int index) {
// Just call super -- the extra work is done by the retained class
super.removeChild(index);
}
/**
* Moves the specified branch group node from its existing location to
* the end of this group node's list of children.
*
*
* If the current child index order array is non-null, the array
* is increased in size by one element, and a new element
* containing the index of the new child is added to the end of
* the array. Thus, this new child will be rendered last.
*
* @param branchGroup the branch group node to move to this node's list
* of children
* @exception CapabilityNotSetException if the appropriate capability is
* not set and this group node is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
@Override
public void moveTo(BranchGroup branchGroup) {
// Just call super -- the extra work is done by the retained class
super.moveTo(branchGroup);
}
/**
* Removes the specified child node from this group node's
* list of children.
* If the specified object is not in the list, the list is not modified.
*
*
* If the current child index order array is non-null, the element
* containing the removed child's index will be removed from the
* child index order array, and the array will be reduced in size
* by one element. If the child removed was not the last child in
* the Group, the values of the child index order array will be
* updated to reflect the indices that were renumbered. More
* formally, each child whose index in the Group node was greater
* than the removed element (before removal) will have its index
* decremented by one.
*
* @param child the child node to be removed.
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
* @exception RestrictedAccessException if this group node is part of
* live or compiled scene graph and the child node being removed is not
* a BranchGroup node
*
* @since Java 3D 1.3
*/
@Override
public void removeChild(Node child) {
// Just call super -- the extra work is done by the retained class
super.removeChild(child);
}
/**
* Removes all children from this Group node.
*
*
* If the current child index order array is non-null, then it is set to
* a zero-length array (the empty set). Note that a zero-length
* child index order array is not the same as a null array in that
* as new elements are added, the child index order array will grow
* and will be used instead of the Group's natural child order.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
* @exception RestrictedAccessException if this group node is part of
* live or compiled scene graph and any of the children being removed are
* not BranchGroup nodes
*
* @since Java 3D 1.3
*/
@Override
public void removeAllChildren() {
// Just call super -- the extra work is done by the retained class
super.removeAllChildren();
}
/**
* Creates the retained mode OrderedGroupRetained object that this
* OrderedGroup component object will point to.
*/
@Override
void createRetained() {
this.retained = new OrderedGroupRetained();
this.retained.setSource(this);
}
void verifyAddStates(Node child) {
if (child instanceof SharedGroup) {
throw new IllegalArgumentException(J3dI18N.getString("Group2"));
}
if (isLiveOrCompiled()) {
if (! (child instanceof BranchGroup))
throw new RestrictedAccessException(J3dI18N.getString("Group12"));
if(!this.getCapability(ALLOW_CHILDREN_EXTEND))
throw new CapabilityNotSetException(J3dI18N.getString("Group16"));
}
}
void verifyChildIndexOrderArray(int[] cIOArr, int plus) {
if (isLiveOrCompiled()) {
if(!this.getCapability(ALLOW_CHILD_INDEX_ORDER_WRITE))
throw new
CapabilityNotSetException(J3dI18N.getString("OrderedGroup4"));
}
if(cIOArr != null) {
if(cIOArr.length != (((GroupRetained)retained).children.size() + plus)) {
throw new
IllegalArgumentException(J3dI18N.getString("OrderedGroup0"));
}
if((checkArr == null) || (checkArr.length != cIOArr.length)) {
checkArr = new boolean[cIOArr.length];
}
Arrays.fill(checkArr, false);
for(int i=0; i= cIOArr.length) {
throw new
IllegalArgumentException(J3dI18N.getString("OrderedGroup2"));
}
else if(checkArr[cIOArr[i]]) {
throw new
IllegalArgumentException(J3dI18N.getString("OrderedGroup3"));
}
else {
checkArr[cIOArr[i]] = true;
}
}
}
}
/**
* Used to create a new instance of the node. This routine is called
* by cloneTree
to duplicate the current node.
* @param forceDuplicate when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @see Node#cloneTree
* @see Node#cloneNode
* @see Node#duplicateNode
* @see NodeComponent#setDuplicateOnCloneTree
*/
@Override
public Node cloneNode(boolean forceDuplicate) {
OrderedGroup og = new OrderedGroup();
og.duplicateNode(this, forceDuplicate);
return og;
}
}