如何在运行时为 javaFX ProgressBar 设置特定的 css 值?
How to set specific css value for javaFX ProgressBar during Runtime?
我的 ProgressBar
:
通常 CSS
.progress-bar > .track {
-fx-background-color: transparent;
}
.progress-bar > .bar {
-fx-background-color: transparent;
-fx-background-image: url('/images/progress_bar.png');
-fx-background-size: 1600px 50px;
-fx-background-repeat: no-repeat;
}
图片 progress_bar.png
是 3 色条,在到达终点时从绿色变为红色。当应用程序为 运行 时,它工作得很好。
我的问题是背景大小的那些硬编码值。这在全高清显示器上完美运行,但在 1366x768 上大部分 yellow/red 部分都被切掉了。我想在 运行 时间内设置此 属性 以匹配屏幕尺寸。这可能吗?
我尝试在 ProgressBar
中使用 setStyle()
方法但没有成功。也许我只是做错了所以如果有人有工作示例...
我也尝试将宽度设置为 100%(而不是像素),但这也不起作用。它只显示压缩条,然后将其拉伸到 100% 宽度。
这是图片:
我认为单独使用 CSS 是不可能的。但是,可以使用自定义 Skin
将 bar
Node
替换为 ImageView
并使用 bar
作为剪辑:
progress.BarBackgroundProgressBarSkin
public class BarBackgroundProgressBarSkin extends ProgressBarSkin {
public BarBackgroundProgressBarSkin(ProgressBar control) {
super(control);
}
private ImageView barBackground;
@Override
protected void initialize() {
super.initialize();
barBackground = new ImageView();
barBackground.setManaged(false);
barBackground.setPreserveRatio(false);
barBackground.getStyleClass().setAll("bar-background");
int barIndex;
List<Node> children = getChildren();
int size = children.size();
for (barIndex = 0; barIndex < size && !children.get(barIndex).getStyleClass().contains("bar"); barIndex++) {
}
Region bar = (Region) children.set(barIndex, barBackground);
barBackground.setClip(bar);
// fill the bar for clipping
bar.setBackground(new Background(new BackgroundFill(Color.WHITE, new CornerRadii(2), new Insets(3, 3, 4, 3))));
}
@Override
protected void layoutChildren(double x, double y, double w, double h) {
// set pos
barBackground.setLayoutX(x);
barBackground.setLayoutY(y);
// set size
barBackground.setFitHeight(h);
barBackground.setFitWidth(w);
super.layoutChildren(x, y, w, h);
}
}
style.css
.progress-bar {
-fx-skin: 'progress.BarBackgroundProgressBarSkin';
}
.progress-bar > .bar-background {
/* your image goes here */
-fx-image: url('http://i.stack.imgur.com/glUAd.png');
}
.progress-bar > .track {
-fx-background-color: transparent;
}
演示
@Override
public void start(Stage primaryStage) {
ProgressBar progressBar = new ProgressBar();
StackPane root = new StackPane();
root.getChildren().add(progressBar);
progressBar.setPrefSize(300, 18);
Scene scene = new Scene(root, 200, 200);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
Timeline tl = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(progressBar.progressProperty(), 0d)),
new KeyFrame(Duration.seconds(10), new KeyValue(progressBar.progressProperty(), 1d, Interpolator.EASE_OUT))
);
tl.setCycleCount(Animation.INDEFINITE);
tl.play();
primaryStage.setScene(scene);
primaryStage.show();
}
我的 ProgressBar
:
.progress-bar > .track {
-fx-background-color: transparent;
}
.progress-bar > .bar {
-fx-background-color: transparent;
-fx-background-image: url('/images/progress_bar.png');
-fx-background-size: 1600px 50px;
-fx-background-repeat: no-repeat;
}
图片 progress_bar.png
是 3 色条,在到达终点时从绿色变为红色。当应用程序为 运行 时,它工作得很好。
我的问题是背景大小的那些硬编码值。这在全高清显示器上完美运行,但在 1366x768 上大部分 yellow/red 部分都被切掉了。我想在 运行 时间内设置此 属性 以匹配屏幕尺寸。这可能吗?
我尝试在 ProgressBar
中使用 setStyle()
方法但没有成功。也许我只是做错了所以如果有人有工作示例...
我也尝试将宽度设置为 100%(而不是像素),但这也不起作用。它只显示压缩条,然后将其拉伸到 100% 宽度。
这是图片:
我认为单独使用 CSS 是不可能的。但是,可以使用自定义 Skin
将 bar
Node
替换为 ImageView
并使用 bar
作为剪辑:
progress.BarBackgroundProgressBarSkin
public class BarBackgroundProgressBarSkin extends ProgressBarSkin {
public BarBackgroundProgressBarSkin(ProgressBar control) {
super(control);
}
private ImageView barBackground;
@Override
protected void initialize() {
super.initialize();
barBackground = new ImageView();
barBackground.setManaged(false);
barBackground.setPreserveRatio(false);
barBackground.getStyleClass().setAll("bar-background");
int barIndex;
List<Node> children = getChildren();
int size = children.size();
for (barIndex = 0; barIndex < size && !children.get(barIndex).getStyleClass().contains("bar"); barIndex++) {
}
Region bar = (Region) children.set(barIndex, barBackground);
barBackground.setClip(bar);
// fill the bar for clipping
bar.setBackground(new Background(new BackgroundFill(Color.WHITE, new CornerRadii(2), new Insets(3, 3, 4, 3))));
}
@Override
protected void layoutChildren(double x, double y, double w, double h) {
// set pos
barBackground.setLayoutX(x);
barBackground.setLayoutY(y);
// set size
barBackground.setFitHeight(h);
barBackground.setFitWidth(w);
super.layoutChildren(x, y, w, h);
}
}
style.css
.progress-bar {
-fx-skin: 'progress.BarBackgroundProgressBarSkin';
}
.progress-bar > .bar-background {
/* your image goes here */
-fx-image: url('http://i.stack.imgur.com/glUAd.png');
}
.progress-bar > .track {
-fx-background-color: transparent;
}
演示
@Override
public void start(Stage primaryStage) {
ProgressBar progressBar = new ProgressBar();
StackPane root = new StackPane();
root.getChildren().add(progressBar);
progressBar.setPrefSize(300, 18);
Scene scene = new Scene(root, 200, 200);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
Timeline tl = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(progressBar.progressProperty(), 0d)),
new KeyFrame(Duration.seconds(10), new KeyValue(progressBar.progressProperty(), 1d, Interpolator.EASE_OUT))
);
tl.setCycleCount(Animation.INDEFINITE);
tl.play();
primaryStage.setScene(scene);
primaryStage.show();
}