modules/controls/src/main/java/javafx/scene/control/skin/ProgressBarSkin.java
Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
@@ -21,52 +21,97 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package com.sun.javafx.scene.control.skin;
+package javafx.scene.control.skin;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import javafx.animation.KeyFrame;
-import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Transition;
-import javafx.beans.InvalidationListener;
import javafx.beans.binding.When;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.value.WritableValue;
import javafx.css.CssMetaData;
import javafx.css.StyleableBooleanProperty;
import javafx.css.StyleableDoubleProperty;
import javafx.css.StyleableProperty;
import javafx.scene.Node;
+import javafx.scene.control.Control;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.util.Duration;
-import com.sun.javafx.css.converters.BooleanConverter;
-import com.sun.javafx.css.converters.SizeConverter;
+import javafx.css.converter.BooleanConverter;
+import javafx.css.converter.SizeConverter;
import javafx.css.Styleable;
-
+/**
+ * Default skin implementation for the {@link ProgressBar} control.
+ *
+ * @see ProgressBar
+ * @since 9
+ */
public class ProgressBarSkin extends ProgressIndicatorSkin {
/***************************************************************************
* *
- * CSS properties *
+ * Private fields *
+ * *
+ **************************************************************************/
+
+ private StackPane bar;
+ private StackPane track;
+ private Region clipRegion;
+
+ // clean up progress so we never go out of bounds or update graphics more than twice per pixel
+ private double barWidth;
+
+
+
+ /***************************************************************************
+ * *
+ * Constructors *
+ * *
+ **************************************************************************/
+
+ /**
+ * Creates a new ProgressBarSkin instance, installing the necessary child
+ * nodes into the Control {@link Control#getChildren() children} list, as
+ * well as the necessary {@link Node#getInputMap() input mappings} for
+ * handling key, mouse, etc events.
+ *
+ * @param control The control that this skin should be installed onto.
+ */
+ public ProgressBarSkin(ProgressBar control) {
+ super(control);
+
+ barWidth = ((int) (control.getWidth() - snappedLeftInset() - snappedRightInset()) * 2 * Math.min(1, Math.max(0, control.getProgress()))) / 2.0F;
+
+ control.widthProperty().addListener(observable -> updateProgress());
+
+ initialize();
+ getSkinnable().requestLayout();
+ }
+
+
+
+ /***************************************************************************
+ * *
+ * Properties *
* *
**************************************************************************/
/**
* The length of the bouncing progress bar in indeterminate state
@@ -202,50 +247,86 @@
/***************************************************************************
* *
- * Private fields *
+ * Public API *
* *
**************************************************************************/
- private StackPane bar;
- private StackPane track;
- private Region clipRegion;
+ /** {@inheritDoc} */
+ @Override public double computeBaselineOffset(double topInset, double rightInset, double bottomInset, double leftInset) {
+ return Node.BASELINE_OFFSET_SAME_AS_HEIGHT;
+ }
- // clean up progress so we never go out of bounds or update graphics more than twice per pixel
- private double barWidth;
+ /** {@inheritDoc} */
+ @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ return Math.max(100, leftInset + bar.prefWidth(getSkinnable().getWidth()) + rightInset);
+ }
+ /** {@inheritDoc} */
+ @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+ return topInset + bar.prefHeight(width) + bottomInset;
+ }
+ /** {@inheritDoc} */
+ @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ return getSkinnable().prefWidth(height);
+ }
- /***************************************************************************
- * *
- * Constructors *
- * *
- **************************************************************************/
- public ProgressBarSkin(ProgressBar control) {
- super(control);
+ /** {@inheritDoc} */
+ @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+ return getSkinnable().prefHeight(width);
+ }
- barWidth = ((int) (control.getWidth() - snappedLeftInset() - snappedRightInset()) * 2 * Math.min(1, Math.max(0, control.getProgress()))) / 2.0F;
+ /** {@inheritDoc} */
+ @Override protected void layoutChildren(final double x, final double y,
+ final double w, final double h) {
- InvalidationListener listener = valueModel -> {
- updateProgress();
- };
- control.widthProperty().addListener(listener);
+ final ProgressIndicator control = getSkinnable();
+ boolean isIndeterminate = control.isIndeterminate();
- initialize();
- getSkinnable().requestLayout();
+ // resize clip
+ clipRegion.resizeRelocate(0, 0, w, h);
+
+ track.resizeRelocate(x, y, w, h);
+ bar.resizeRelocate(x, y, isIndeterminate ? getIndeterminateBarLength() : barWidth, h);
+
+ // things should be invisible only when well below minimum length
+ track.setVisible(true);
+
+ // width might have changed so recreate our animation if needed
+ if (isIndeterminate) {
+ createIndeterminateTimeline();
+ if (getSkinnable().impl_isTreeVisible()) {
+ indeterminateTransition.play();
+ }
+
+ // apply clip
+ bar.setClip(clipRegion);
+ } else if (indeterminateTransition != null) {
+ indeterminateTransition.stop();
+ indeterminateTransition = null;
+
+ // remove clip
+ bar.setClip(null);
+ bar.setScaleX(1);
+ bar.setTranslateX(0);
+ clipRegion.translateXProperty().unbind();
+ }
}
+
/***************************************************************************
* *
- * Implementation *
+ * Private implementation *
* *
**************************************************************************/
- @Override protected void initialize() {
+ /** {@inheritDoc} */
+ @Override void initialize() {
track = new StackPane();
track.getStyleClass().setAll("track");
bar = new StackPane();
bar.getStyleClass().setAll("bar");
@@ -267,12 +348,12 @@
clipRegion.setBackground(new Background(fills));
}
});
}
- @Override
- protected void createIndeterminateTimeline() {
+ /** {@inheritDoc} */
+ @Override void createIndeterminateTimeline() {
if (indeterminateTransition != null) indeterminateTransition.stop();
ProgressIndicator control = getSkinnable();
final double w = control.getWidth() - (snappedLeftInset() + snappedRightInset());
final double startX = getIndeterminateBarEscape() ? -getIndeterminateBarLength() : 0;
@@ -287,12 +368,12 @@
otherwise(bar.translateXProperty().negate()));
}
boolean wasIndeterminate = false;
- @Override
- protected void updateProgress() {
+ /** {@inheritDoc} */
+ @Override void updateProgress() {
ProgressIndicator control = getSkinnable();
// RT-33789: if the ProgressBar was indeterminate and still is indeterminate, don't update the bar width
final boolean isIndeterminate = control.isIndeterminate();
if (!(isIndeterminate && wasIndeterminate)) {
barWidth = ((int) (control.getWidth() - snappedLeftInset() - snappedRightInset()) * 2 * Math.min(1, Math.max(0, control.getProgress()))) / 2.0F;
@@ -300,78 +381,10 @@
}
wasIndeterminate = isIndeterminate;
}
- /***************************************************************************
- * *
- * Layout *
- * *
- **************************************************************************/
-
- @Override
- public double computeBaselineOffset(double topInset, double rightInset, double bottomInset, double leftInset) {
- return Node.BASELINE_OFFSET_SAME_AS_HEIGHT;
- }
-
- @Override
- protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- return Math.max(100, leftInset + bar.prefWidth(getSkinnable().getWidth()) + rightInset);
- }
-
- @Override
- protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
- return topInset + bar.prefHeight(width) + bottomInset;
- }
-
- @Override
- protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- return getSkinnable().prefWidth(height);
- }
-
- @Override
- protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
- return getSkinnable().prefHeight(width);
- }
-
- @Override
- protected void layoutChildren(final double x, final double y,
- final double w, final double h) {
-
- final ProgressIndicator control = getSkinnable();
- boolean isIndeterminate = control.isIndeterminate();
-
- // resize clip
- clipRegion.resizeRelocate(0, 0, w, h);
-
- track.resizeRelocate(x, y, w, h);
- bar.resizeRelocate(x, y, isIndeterminate ? getIndeterminateBarLength() : barWidth, h);
-
- // things should be invisible only when well below minimum length
- track.setVisible(true);
-
- // width might have changed so recreate our animation if needed
- if (isIndeterminate) {
- createIndeterminateTimeline();
- if (getSkinnable().impl_isTreeVisible()) {
- indeterminateTransition.play();
- }
-
- // apply clip
- bar.setClip(clipRegion);
- } else if (indeterminateTransition != null) {
- indeterminateTransition.stop();
- indeterminateTransition = null;
-
- // remove clip
- bar.setClip(null);
- bar.setScaleX(1);
- bar.setTranslateX(0);
- clipRegion.translateXProperty().unbind();
- }
- }
-
/***************************************************************************
* *
* Stylesheet Handling *
* *
@@ -467,26 +480,32 @@
STYLEABLES = Collections.unmodifiableList(styleables);
}
}
/**
- * @return The CssMetaData associated with this class, which may include the
+ * Returns the CssMetaData associated with this class, which may include the
* CssMetaData of its super classes.
*/
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return StyleableProperties.STYLEABLES;
}
/**
* {@inheritDoc}
*/
- @Override
- public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
+ @Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
return getClassCssMetaData();
}
+
+ /***************************************************************************
+ * *
+ * Support classes *
+ * *
+ **************************************************************************/
+
private static class IndeterminateTransition extends Transition {
private final WeakReference<ProgressBarSkin> skin;
private final double startX;
private final double endX;
private final boolean flip;