changeset 1696:c3d496ae74df

RT-20702 : Indeterminate progressbar uses too much CPU (even when invisible)
author mickf
date Tue, 28 Aug 2012 16:50:55 +0100
parents 9d0822d9d338
children e0abb4b9d652
files javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressBarSkin.java javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java
diffstat 2 files changed, 88 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressBarSkin.java	Tue Aug 28 08:39:34 2012 +1200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressBarSkin.java	Tue Aug 28 16:50:55 2012 +0100
@@ -62,7 +62,7 @@
      *                                                                         *
      **************************************************************************/
 
-    private StackPane bar;
+    private Bar bar;
     private StackPane track;
     private Rectangle clipRectangle;
 
@@ -221,7 +221,7 @@
                 }
                 
                 if (indeterminateTimeline != null) {
-                    if (getSkinnable().isVisible() && getSkinnable().getScene() != null) {
+                    if (getSkinnable().impl_isTreeVisible() && getSkinnable().getScene() != null) {
                         indeterminateTimeline.play();
                     }
                     else {
@@ -248,7 +248,9 @@
                     if (getSkinnable().getScene() != null && getSkinnable().isIndeterminate()) {
                         timelineNulled = false;
                         createIndeterminateTimeline();
-                        indeterminateTimeline.play();
+                        if (getSkinnable().impl_isTreeVisible()) {
+                            indeterminateTimeline.play();
+                        }
                         requestLayout();
                     }
                 }
@@ -284,12 +286,42 @@
         track = new StackPane();
         track.getStyleClass().setAll("track");
 
-        bar = new StackPane();
+        bar = new Bar(this);
         bar.getStyleClass().setAll("bar");
 
         getChildren().setAll(track, bar);
     }
 
+    void pauseBar(boolean pause) {
+        if (indeterminateTimeline != null) {
+            if (pause) {
+                indeterminateTimeline.pause();
+            }
+            else {
+                indeterminateTimeline.play();
+            }
+        }
+    }
+
+    class Bar extends StackPane {
+        ProgressBarSkin pbSkin;
+        Bar(ProgressBarSkin pb) {
+            super();
+            pbSkin = pb;
+            InvalidationListener treeVisibilityListener = new InvalidationListener() {
+                    @Override public void invalidated(Observable valueModel) {
+                        if (getSkinnable().impl_isTreeVisible()) {
+                            pbSkin.pauseBar(false);
+                        }
+                        else {
+                            pbSkin.pauseBar(true);
+                        }
+                    }
+                };
+            impl_treeVisibleProperty().addListener(treeVisibilityListener);
+        }
+    }
+
     private void createIndeterminateTimeline() {
         if (indeterminateTimeline != null) indeterminateTimeline.stop();
 
@@ -394,7 +426,7 @@
         // width might have changed so recreate our animation if needed
         if (isIndeterminate) {
             createIndeterminateTimeline();
-            if (getSkinnable().isVisible()) {
+            if (getSkinnable().impl_isTreeVisible()) {
                 indeterminateTimeline.play();
             }
         } else if (indeterminateTimeline != null) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Tue Aug 28 08:39:34 2012 +1200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Tue Aug 28 16:50:55 2012 +0100
@@ -63,6 +63,9 @@
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.value.WritableValue;
 
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+
 public class ProgressIndicatorSkin extends SkinBase<ProgressIndicator, ProgressIndicatorBehavior<ProgressIndicator>> {
 
     /***************************************************************************
@@ -115,7 +118,7 @@
                 }
                 
                 if (spinner != null) {
-                    if (getSkinnable().isVisible() && getSkinnable().getScene() != null) {
+                    if (getSkinnable().impl_isTreeVisible() && getSkinnable().getScene() != null) {
                         spinner.indeterminateTimeline.play();
                     }
                     else {
@@ -145,7 +148,9 @@
                         timelineNulled = false;
                         spinner = new IndeterminateSpinner(getSkinnable(), ProgressIndicatorSkin.this);
                         getChildren().add(spinner);
-                        spinner.indeterminateTimeline.play();
+                        if (getSkinnable().impl_isTreeVisible()) {
+                            spinner.indeterminateTimeline.play();
+                        }
                         requestLayout();
                     }
                 }
@@ -167,7 +172,7 @@
             spinner = new IndeterminateSpinner(control, this);
             getChildren().clear();
             getChildren().add(spinner);
-            if (getSkinnable().isVisible()) {
+            if (getSkinnable().impl_isTreeVisible()) {
                 spinner.indeterminateTimeline.play();
             }
         } else {
@@ -390,8 +395,8 @@
     static class IndeterminateSpinner extends Region {
 
         private ProgressIndicator control;
-        private ProgressIndicatorSkin skin;
-        private Group childrenG;
+        protected ProgressIndicatorSkin skin;
+        private IndicatorPaths pathsG;
         Scale scaleTransform;
         Rotate rotateTransform;
 
@@ -405,15 +410,15 @@
             skin.svgpaths = FXCollections.<SVGPath>observableArrayList();
             skin.setColors(skin.getProgressColor());
 
-            childrenG = new Group();
+            pathsG = new IndicatorPaths(this);
 
             scaleTransform = new Scale();
 
             rotateTransform = new Rotate();
             rotateTransform.setAngle(angle);
 
-            childrenG.getChildren().clear();
-            childrenG.getChildren().addAll(skin.svgpaths);
+            pathsG.getChildren().clear();
+            pathsG.getChildren().addAll(skin.svgpaths);
 
             indeterminateTimeline = new Timeline();
             indeterminateTimeline.setCycleCount(Timeline.INDEFINITE);
@@ -431,10 +436,42 @@
             indeterminateTimeline.getKeyFrames().addAll(keyframes);
 
             getChildren().clear();
-            getChildren().addAll(childrenG);
+            getChildren().addAll(pathsG);
             requestLayout();
         }
 
+        void pauseIndicator(boolean pause) {
+            if (indeterminateTimeline != null) {
+                if (pause) {
+                    indeterminateTimeline.pause();
+                }
+                else {
+                    indeterminateTimeline.play();
+                }
+            }
+        }
+
+
+    class IndicatorPaths extends Group {
+        IndeterminateSpinner piSkin;
+        IndicatorPaths(IndeterminateSpinner pi) {
+            super();
+            piSkin = pi;
+            InvalidationListener treeVisibilityListener = new InvalidationListener() {
+                    @Override public void invalidated(Observable valueModel) {
+                        if (piSkin.skin.getSkinnable().impl_isTreeVisible()) {
+                            piSkin.pauseIndicator(false);
+                        }
+                        else {
+                            piSkin.pauseIndicator(true);
+                        }
+                    }
+                };
+            impl_treeVisibleProperty().addListener(treeVisibilityListener);
+        }
+    }
+
+
         @Override protected void layoutChildren() {
             double radiusW = (control.getWidth() - (skin.getInsets().getLeft() + skin.getInsets().getRight())) / 2;
             double radiusH = (control.getHeight() - (skin.getInsets().getTop() + skin.getInsets().getBottom())) / 2;
@@ -446,14 +483,14 @@
             rotateTransform.setPivotX(radius);
             rotateTransform.setPivotY(radius);
 
-            childrenG.getTransforms().clear();
-            childrenG.getTransforms().addAll(scaleTransform, rotateTransform);
+            pathsG.getTransforms().clear();
+            pathsG.getTransforms().addAll(scaleTransform, rotateTransform);
 
             double diameter = radius*2;
-            childrenG.resize(diameter, diameter);
+            pathsG.resize(diameter, diameter);
 
-            childrenG.setLayoutX(skin.getInsets().getLeft()+(radiusW - radius));
-            childrenG.setLayoutY(skin.getInsets().getTop()+(radiusH - radius));
+            pathsG.setLayoutX(skin.getInsets().getLeft()+(radiusW - radius));
+            pathsG.setLayoutY(skin.getInsets().getTop()+(radiusH - radius));
         }
 
         private Timeline indeterminateTimeline;