【发布时间】:2013-09-03 13:56:22
【问题描述】:
我想知道是否可以用外观制作进度条,“progressbar Animated bootstrap”。横条纹。
【问题讨论】:
-
您的意思是“我可以使用现有的实现吗”或“我可以通过一些额外的工作让我的组件看起来像这样”吗?第一个问题的答案是否定的,但可以通过一些定制来实现。
我想知道是否可以用外观制作进度条,“progressbar Animated bootstrap”。横条纹。
【问题讨论】:
如果有人对@jewelsea 答案的动画版感兴趣,请查看以下代码。
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();
}
}
【讨论】:
在另一个answer 中,我已经解释了如何做到这一点。 就像珠宝海说的那样,我用时间线为洞进度条设置了动画。但是在运行时没有查找或样式更改(不推荐两者)。
您必须多写一点 css,但它会运行顺畅且不会占用太多 CPU。
这里是来自 Jewelsea 的编辑代码:
文件: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();
}
}
还有完整的 CSS:
文件: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%
);
}
【讨论】:
带有静态条纹的进度条
这是一个 JavaFX ProgressBar,它看起来像来自 Bootstrap 的静态条纹进度条。
条纹渐变完全在 css 中设置,Java 代码只是一个测试工具。
文件: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%
);
}
文件: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();
}
}
带有动画条纹的进度条
JavaFX 有很好的animation facilities,如果您愿意,它可以让您在进度条内设置渐变动画。
一种方法是在栏显示在屏幕上之后在栏上进行节点查找,并在Timeline 中修改栏的样式属性,类似于How to make an animation with CSS in JavaFX? 中应用的技术
就我个人而言,我发现进度条上的动画条纹很烦人。
为此编写实际代码留给读者作为练习。
【讨论】: