ProgressBar Animated Javafx
Asked Answered
S

3

4

I wonder if it is possible to make a progressbar with the appearance,"progressbar Animated bootstrap". With stripes going sideways.

http://getbootstrap.com/2.3.2/components.html#progress

Stillhunt answered 30/8, 2013 at 18:48 Comment(1)
Do you mean possible as in 'is there an existing implementation I can use' or possible as 'can I get my component to look like this with some additional work'? The answer to the first question is no, but it is possible with some customization.Roughandtumble
S
17

ProgressBar with Static Stripes

Here is a JavaFX ProgressBar which looks like a static striped progress bar from Bootstrap.

striped

The stripe gradient is set entirely in css, the Java code is just a test harness.

File: striped-progress.css

.progress-bar > .bar {
    -fx-background-color: linear-gradient(
        from 0px .75em to .75em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
    );
}

File: StripedProgress.java

import javafx.animation.*;
import javafx.application.Application;
import javafx.event.*;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

/** Displays progress on a striped progress bar */
public class StripedProgress extends Application {
  public static void main(String[] args) { launch(args); }

  @Override public void start(final Stage stage) {
    ProgressBar bar = new ProgressBar(0);
    bar.setPrefSize(200, 24);

    Timeline task = new Timeline(
        new KeyFrame(
                Duration.ZERO,       
                new KeyValue(bar.progressProperty(), 0)
        ),
        new KeyFrame(
                Duration.seconds(2), 
                new KeyValue(bar.progressProperty(), 1)
        )
    );

    Button button = new Button("Go!");
    button.setOnAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent actionEvent) {
            task.playFromStart();
        }
    });

    VBox layout = new VBox(10);
    layout.getChildren().setAll(
        bar,
        button
    );
    layout.setPadding(new Insets(10));
    layout.setAlignment(Pos.CENTER);

    layout.getStylesheets().add(
        getClass().getResource(
            "striped-progress.css"
        ).toExternalForm()
    );

    stage.setScene(new Scene(layout));
    stage.show();
  }
}

ProgressBar with Animated Stripes

JavaFX has good animation facilities which will allow you to animate the gradient within the progress bar if you wish.

One way to do that is to do a node lookup on the bar after the bar has been displayed on the screen and modify the style property of the bar in a Timeline, similar to the technique applied in: How to make an animation with CSS in JavaFX?

Personally, I find animated stripes on progress bars annoying.

Writing the actual code for this is left as an exercise for the reader.

Shaunda answered 31/8, 2013 at 0:22 Comment(0)
G
3

In another answer I have explained how to do this. Like jewelsea said, I animated the hole progress-bar with a timeline. But without a lookup or style change on runtime(both is not really recommended).

You must write a bit more css but then it runs smoothly and without much CPU usage.

Here the edited code from jewelsea:

File: StripedProgress.java

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.css.PseudoClass;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * Displays progress on a striped progress bar
 */
public class StripedProgress extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage stage) {
        ProgressBar bar = new ProgressBar(0);
        bar.setPrefSize(200, 24);

        Timeline task = new Timeline(
                new KeyFrame(
                        Duration.ZERO,
                        new KeyValue(bar.progressProperty(), 0)
                ),
                new KeyFrame(
                        Duration.seconds(2),
                        new KeyValue(bar.progressProperty(), 1)
                )
        );

        // Set the max status
        int maxStatus = 12;
        // Create the Property that holds the current status count
        IntegerProperty statusCountProperty = new SimpleIntegerProperty(1);
        // Create the timeline that loops the statusCount till the maxStatus
        Timeline timelineBar = new Timeline(
                new KeyFrame(
                        // Set this value for the speed of the animation
                        Duration.millis(300),
                        new KeyValue(statusCountProperty, maxStatus)
                )
        );
        // The animation should be infinite
        timelineBar.setCycleCount(Timeline.INDEFINITE);
        timelineBar.play();
        // Add a listener to the statusproperty
        statusCountProperty.addListener((ov, statusOld, statusNewNumber) -> {
            int statusNew = statusNewNumber.intValue();
            // Remove old status pseudo from progress-bar
            bar.pseudoClassStateChanged(PseudoClass.getPseudoClass("status" + statusOld.intValue()), false);
            // Add current status pseudo from progress-bar
            bar.pseudoClassStateChanged(PseudoClass.getPseudoClass("status" + statusNew), true);
        });

        Button button = new Button("Go!");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                task.playFromStart();
            }
        });

        VBox layout = new VBox(10);
        layout.getChildren().setAll(
                bar,
                button
        );
        layout.setPadding(new Insets(10));
        layout.setAlignment(Pos.CENTER);

        layout.getStylesheets().add(
                getClass().getResource(
                        "/styles/striped-progress.css"
                ).toExternalForm()
        );

        stage.setScene(new Scene(layout));
        stage.show();
    }
}

And the full CSS:

File: striped-progress.css

.progress-bar:status1 > .bar {
    -fx-background-color: linear-gradient(
        from 0em 0.75em to 0.75em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status2 > .bar {
    -fx-background-color: linear-gradient(
        from 0.25em 0.75em to 1em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status3 > .bar {
    -fx-background-color: linear-gradient(
        from 0.5em 0.75em to 1.25em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status4 > .bar {
    -fx-background-color: linear-gradient(
        from 0.75em 0.75em to 1.5em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status5 > .bar {
    -fx-background-color: linear-gradient(
        from 1em 0.75em to 1.75em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status6 > .bar {
    -fx-background-color: linear-gradient(
        from 1.25em 0.75em to 2em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status7 > .bar {
    -fx-background-color: linear-gradient(
        from 1.5em 0.75em to 2.25em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status8 > .bar {
    -fx-background-color: linear-gradient(
        from 1.75em 0.75em to 2.5em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status9 > .bar {
    -fx-background-color: linear-gradient(
        from 2em 0.75em to 2.75em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status10 > .bar {
    -fx-background-color: linear-gradient(
        from 2.25em 0.75em to 3em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status11 > .bar {
    -fx-background-color: linear-gradient(
        from 2.5em 0.75em to 3.25em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
.progress-bar:status12 > .bar {
    -fx-background-color: linear-gradient(
        from 2.75em 0.75em to 3.5em 0px,
        repeat,
        -fx-accent 0%,
        -fx-accent 49%,
        derive(-fx-accent, 30%) 50%,
        derive(-fx-accent, 30%) 99%
        );
}
Gaylor answered 18/12, 2014 at 8:35 Comment(2)
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From ReviewHolt
i edited my answer so it meets the criticism points from the reviewers. @MWiesner: It provides an answer to this question if you looked at the link :-/ a better one then the "accepted" in my opinion. now i think it does not earn a downvote :-(Gaylor
F
1

If anyone is interested for the animation version of @jewelsea answer, please check the below code.

enter image description here

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * Displays progress on a striped progress bar
 */
public class StripedProgress extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage stage) {
        ObjectProperty<Node> node = new SimpleObjectProperty<>();
        ProgressBar bar = new ProgressBar(0) {
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                if (node.get() == null) {
                    Node n = lookup(".bar");
                    node.set(n);
                    int stripWidth = 10;
                    IntegerProperty x = new SimpleIntegerProperty(0);
                    IntegerProperty y = new SimpleIntegerProperty(stripWidth);
                    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(35), e -> {
                        x.set(x.get() + 1);
                        y.set(y.get() + 1);
                        String style = "-fx-background-color: linear-gradient(from " + x.get() + "px " + x.get() + "px to " + y.get() + "px " + y.get() + "px, repeat, -fx-accent 50%, derive(-fx-accent, 30%) 50%);";
                        n.setStyle(style);
                        if (x.get() >= stripWidth * 2) {
                            x.set(0);
                            y.set(stripWidth);
                        }
                    }));
                    timeline.setCycleCount(Animation.INDEFINITE);
                    progressProperty().addListener((obs, old, val) -> {
                        if (old.doubleValue() <= 0) {
                            timeline.playFromStart();
                        }
                    });
                }
            }
        };
        bar.setPrefSize(200, 24);

        Timeline task = new Timeline(
                new KeyFrame(
                        Duration.ZERO,
                        new KeyValue(bar.progressProperty(), 0)
                ),
                new KeyFrame(
                        Duration.seconds(10),
                        new KeyValue(bar.progressProperty(), 1)
                )
        );

        Button button = new Button("Go!");
        button.setOnAction(actionEvent -> task.playFromStart());

        VBox layout = new VBox(10);
        layout.getChildren().setAll(bar, button);
        layout.setPadding(new Insets(10));
        layout.setAlignment(Pos.CENTER);
        
        stage.setScene(new Scene(layout));
        stage.show();
    }
}
Fulmar answered 20/12, 2021 at 1:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.