changeset 1748:3546a0a8e2cd

BaseObservableList implementation in com.sun. package
author Martin Sladecek <martin.sladecek@oracle.com>
date Thu, 13 Sep 2012 16:36:07 +0200
parents df3029cbea31
children e27fb70af786
files javafx-ui-common/src/javafx/scene/Parent.java javafx-ui-controls/src/javafx/scene/control/ToggleGroup.java
diffstat 2 files changed, 136 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/javafx/scene/Parent.java	Tue Sep 11 14:47:38 2012 +0200
+++ b/javafx-ui-common/src/javafx/scene/Parent.java	Thu Sep 13 16:36:07 2012 +0200
@@ -41,7 +41,7 @@
 import com.sun.javafx.TempState;
 import com.sun.javafx.Utils;
 import com.sun.javafx.collections.TrackableObservableList;
-import com.sun.javafx.collections.VetoableObservableList;
+import com.sun.javafx.collections.VetoableListDecorator;
 import com.sun.javafx.collections.annotations.ReturnsUnmodifiableCollection;
 import com.sun.javafx.css.Selector;
 import com.sun.javafx.css.StyleManager;
@@ -222,13 +222,126 @@
      * @defaultValue empty
      * @since JavaFX 1.3
      */
-    private final ObservableList<Node> children = new VetoableObservableList<Node>() {
-        // set to true if either childRemoved or childAdded returns
-        // true. These functions will indicate whether the geom
-        // bounds for the parent have changed
-        private boolean geomChanged;
-        private boolean childrenModified;
 
+    // set to true if either childRemoved or childAdded returns
+    // true. These functions will indicate whether the geom
+    // bounds for the parent have changed
+    private boolean geomChanged;
+    private boolean childrenModified;
+    private final ObservableList<Node> children = new VetoableListDecorator<Node>(new TrackableObservableList<Node>() {
+
+
+        protected void onChanged(Change<Node> c) {
+            // proceed with updating the scene graph
+            if (childrenModified) {
+                unmodifiableManagedChildren = null;
+                boolean relayout = false;
+
+                while (c.next()) {
+                    int from = c.getFrom();
+                    int to = c.getTo();
+                    for (int i = from; i < to; ++i) {
+                        Node n = children.get(i);
+                        if (n.getParent() != null && n.getParent() != Parent.this) {
+                            if (warnOnAutoMove) {
+                                java.lang.System.err.println("WARNING added to a new parent without first removing it from its current");
+                                java.lang.System.err.println("    parent. It will be automatically removed from its current parent.");
+                                java.lang.System.err.println("    node=" + n + " oldparent= " + n.getParent() + " newparent=" + this);
+                            }
+                            n.getParent().children.remove(n);
+                            if (n.isManaged()) {
+                                relayout = true;
+                            }
+                            if (warnOnAutoMove) {
+                                Thread.dumpStack();
+                            }
+                        }
+                    }
+
+                    List<Node> removed = c.getRemoved();
+                    int removedSize = removed.size();
+                    for (int i = 0; i < removedSize; ++i) {
+                        if (removed.get(i).isManaged()) {
+                            relayout = true;
+                        }
+                    }
+
+                    // update the parent and scene for each new node
+                    for (int i = from; i < to; ++i) {
+                        Node node = children.get(i);
+                        if (node.isManaged()) {
+                            relayout = true;
+                        }
+                        node.setParent(Parent.this);
+                        node.setScene(getScene());
+                        // assert !node.boundsChanged;
+                        if (node.isVisible()) {
+                            geomChanged = true;
+                            childIncluded(node);
+                        }
+                    }
+                }
+
+                // check to see if the number of children exceeds
+                // DIRTY_CHILDREN_THRESHOLD and dirtyChildren is null.
+                // If so, then we need to create dirtyChildren and
+                // populate it.
+                if (dirtyChildren == null && children.size() > DIRTY_CHILDREN_THRESHOLD) {
+                    dirtyChildren =
+                            new ArrayList<Node>(2 * DIRTY_CHILDREN_THRESHOLD);
+                    // only bother populating children if geom has
+                    // changed, otherwise there is no need
+                    if (dirtyChildrenCount > 0) {
+                        int size = children.size();
+                        for (int i = 0; i < size; ++i) {
+                            Node ch = children.get(i);
+                            if (ch.isVisible() && ch.boundsChanged) {
+                                dirtyChildren.add(ch);
+                            }
+                        }
+                    }
+                }
+
+                if (geomChanged) {
+                    impl_geomChanged();
+                }
+
+                //
+                // Note that the styles of a child do not affect the parent or
+                // its siblings. Thus, it is only necessary to reapply css to
+                // the Node just added and not to this parent and all of its
+                // children. So the following call to impl_reapplyCSS was moved
+                // to Node.parentProperty. The original comment and code were
+                // purposely left here as documentation should there be any
+                // question about how the code used to work and why the change
+                // was made.
+                //
+                // if children have changed then I need to reapply
+                // CSS from this node on down
+//                impl_reapplyCSS();
+                //
+
+                // request layout if a Group subclass has overridden doLayout OR
+                // if one of the new children needs layout, in which case need to ensure
+                // the needsLayout flag is set all the way to the root so the next layout
+                // pass will reach the child.
+                if (relayout) {
+                    requestLayout();
+                }
+            }
+
+            // Note the starting index at which we need to update the
+            // PGGroup on the next update, and mark the children dirty
+            c.reset();
+            c.next();
+            if (startIdx > c.getFrom()) {
+                startIdx = c.getFrom();
+            }
+
+            impl_markDirty(DirtyBits.PARENT_CHILDREN);
+        }
+
+    }) {
         @Override
         protected void onProposedChange(final List<Node> newNodes, int[] toBeRemoved) {
             if (ignoreChildrenTrigger) {
@@ -369,117 +482,6 @@
             }
         }
 
-        @Override
-        protected void onChanged(Change<Node> c) {
-            // proceed with updating the scene graph
-            if (childrenModified) {
-                unmodifiableManagedChildren = null;
-                boolean relayout = false;
-
-                while (c.next()) {
-                    int from = c.getFrom();
-                    int to = c.getTo();
-                    for (int i = from; i < to; ++i) {
-                        Node n = children.get(i);
-                        if (n.getParent() != null && n.getParent() != Parent.this) {
-                            if (warnOnAutoMove) {
-                                java.lang.System.err.println("WARNING added to a new parent without first removing it from its current");
-                                java.lang.System.err.println("    parent. It will be automatically removed from its current parent.");
-                                java.lang.System.err.println("    node=" + n + " oldparent= " + n.getParent() + " newparent=" + this);
-                            }
-                            n.getParent().children.remove(n);
-                            if (n.isManaged()) {
-                                relayout = true;
-                            }
-                            if (warnOnAutoMove) {
-                                Thread.dumpStack();
-                            }
-                        }
-                    }
-
-                    List<Node> removed = c.getRemoved();
-                    int removedSize = removed.size();
-                    for (int i = 0; i < removedSize; ++i) {
-                        if (removed.get(i).isManaged()) {
-                            relayout = true;
-                        }
-                    }
-
-                    // update the parent and scene for each new node
-                    for (int i = from; i < to; ++i) {
-                        Node node = children.get(i);
-                        if (node.isManaged()) {
-                            relayout = true;
-                        }
-                        node.setParent(Parent.this);
-                        node.setScene(getScene());
-                        // assert !node.boundsChanged;
-                        if (node.isVisible()) {
-                            geomChanged = true;
-                            childIncluded(node);
-                        }
-                    }
-                }
-
-                // check to see if the number of children exceeds
-                // DIRTY_CHILDREN_THRESHOLD and dirtyChildren is null.
-                // If so, then we need to create dirtyChildren and
-                // populate it.
-                if (dirtyChildren == null && children.size() > DIRTY_CHILDREN_THRESHOLD) {
-                    dirtyChildren =
-                            new ArrayList<Node>(2 * DIRTY_CHILDREN_THRESHOLD);
-                    // only bother populating children if geom has
-                    // changed, otherwise there is no need
-                    if (dirtyChildrenCount > 0) {
-                        int size = children.size();
-                        for (int i = 0; i < size; ++i) {
-                            Node ch = children.get(i);
-                            if (ch.isVisible() && ch.boundsChanged) {
-                                dirtyChildren.add(ch);
-                            }
-                        }
-                    }
-                }
-
-                if (geomChanged) {
-                    impl_geomChanged();
-                }
-
-                //
-                // Note that the styles of a child do not affect the parent or
-                // its siblings. Thus, it is only necessary to reapply css to
-                // the Node just added and not to this parent and all of its
-                // children. So the following call to impl_reapplyCSS was moved
-                // to Node.parentProperty. The original comment and code were
-                // purposely left here as documentation should there be any
-                // question about how the code used to work and why the change
-                // was made.
-                //
-                // if children have changed then I need to reapply
-                // CSS from this node on down
-//                impl_reapplyCSS();
-                //
-
-                // request layout if a Group subclass has overridden doLayout OR
-                // if one of the new children needs layout, in which case need to ensure
-                // the needsLayout flag is set all the way to the root so the next layout
-                // pass will reach the child.
-                if (relayout) {
-                    requestLayout();
-                }
-            }
-
-            // Note the starting index at which we need to update the
-            // PGGroup on the next update, and mark the children dirty
-            c.reset();
-            c.next();
-            if (startIdx > c.getFrom()) {
-                startIdx = c.getFrom();
-            }
-
-            impl_markDirty(DirtyBits.PARENT_CHILDREN);
-        }
-
         private String constructExceptionMessage(
                 String cause, Node offendingNode) {
             final StringBuilder sb = new StringBuilder("Children: ");
@@ -565,8 +567,8 @@
                 Node e = children.get(i);
                 if (e.isManaged()) {
                     unmodifiableManagedChildren.add(e);
+                        }
                 }
-            }
         }
         return (List<E>)unmodifiableManagedChildren;
     }
--- a/javafx-ui-controls/src/javafx/scene/control/ToggleGroup.java	Tue Sep 11 14:47:38 2012 +0200
+++ b/javafx-ui-controls/src/javafx/scene/control/ToggleGroup.java	Thu Sep 13 16:36:07 2012 +0200
@@ -29,8 +29,8 @@
 import javafx.beans.property.ReadOnlyObjectWrapper;
 import javafx.collections.ListChangeListener.Change;
 import javafx.collections.ObservableList;
-
-import com.sun.javafx.collections.VetoableObservableList;
+import com.sun.javafx.collections.VetoableListDecorator;
+import com.sun.javafx.collections.TrackableObservableList;
 
 /**
  * A class which contains a reference to all {@code Toggles} whose
@@ -52,19 +52,7 @@
         return toggles;
     }
 
-    private final ObservableList<Toggle> toggles = new VetoableObservableList<Toggle>() {
-        @Override protected void onProposedChange(List<Toggle> toBeAdded, int... indexes) {
-            for (Toggle t: toBeAdded) {
-                if (indexes[0] == 0 && indexes[1] == size()) {
-                    // we don't need to check for duplicates because this is a setAll.                    
-                    break;
-                }
-                if (toggles.contains(t)) {
-                    throw new IllegalArgumentException("Duplicate toggles are not allow in a ToggleGroup.");
-                }
-            }
-        }
-
+    private final ObservableList<Toggle> toggles = new VetoableListDecorator<Toggle>(new TrackableObservableList<Toggle>() {
         @Override protected void onChanged(Change<Toggle> c) {            
             while (c.next()) {
                 // Look through the removed toggles, and if any of them was the
@@ -99,6 +87,18 @@
                 }
             }
         }
+    }) {
+        @Override protected void onProposedChange(List<Toggle> toBeAdded, int... indexes) {
+            for (Toggle t: toBeAdded) {
+                if (indexes[0] == 0 && indexes[1] == size()) {
+                    // we don't need to check for duplicates because this is a setAll.
+                    break;
+                }
+                if (toggles.contains(t)) {
+                    throw new IllegalArgumentException("Duplicate toggles are not allow in a ToggleGroup.");
+                }
+            }
+        }
     };
 
     private final ReadOnlyObjectWrapper<Toggle> selectedToggle = new ReadOnlyObjectWrapper<Toggle>() {