有一个具有 2 种或更多背景颜色的矩形吗?像50%黑色,50%红色?
我想制作一个生命条来显示剩余的生命值。我想我可以做一些类似的东西:
life = 100
width with green color = 99,98,....,0%
width with gray color = 0,1,...,100% (end of game)
有很多不同的方法可以做到这一点。我可能更喜欢使用ProgressBar
中已经定义的功能,并使用 CSS 来设置它的样式以获得您想要的颜色;或者只是使用常规Pane
并使用两种嵌套背景颜色并改变插图。这些以及使用矩形等的各种其他选项显示在下面的演示中:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TwoColoredRectangle extends Application {
@Override
public void start(Stage primaryStage) {
// property to change:
DoubleProperty life = new SimpleDoubleProperty(100);
// "animate" the property for demo:
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(life, 100)),
new KeyFrame(Duration.seconds(2), new KeyValue(life, 0))
);
// button to set the animation going:
Button startButton = new Button("Start");
startButton.setOnAction(e -> timeline.playFromStart());
VBox root = new VBox(5);
// Solution 1. One rectangle on another:
Rectangle base = new Rectangle(0, 0, 400, 20);
base.setFill(Color.GRAY);
Rectangle lifeRect = new Rectangle(0, 0, 400, 20);
lifeRect.setFill(Color.GREEN);
lifeRect.widthProperty().bind(life.multiply(4));
Pane solutionPane1 = new Pane(base, lifeRect);
root.getChildren().add(createSolutionPane("Dynamic rectangle on fixed rectangle", solutionPane1));
// Solution 2: Two rectangles changing together:
Rectangle leftRect = new Rectangle();
leftRect.setHeight(20);
leftRect.setFill(Color.GREEN);
Rectangle rightRect = new Rectangle();
rightRect.setHeight(20);
rightRect.setFill(Color.GRAY);
leftRect.widthProperty().bind(life.multiply(4));
rightRect.xProperty().bind(leftRect.widthProperty());
rightRect.widthProperty().bind(life.multiply(-4).add(400));
Pane solutionPane2 = new Pane(leftRect, rightRect);
root.getChildren().add(createSolutionPane("Two dynamic rectangles", solutionPane2));
// Solution 3: Green rectangle on gray-styled pane:
Pane basePane = new Pane();
basePane.setMinSize(400, 20);
basePane.setMaxSize(400, 20);
// gray color will be defined in CSS:
basePane.getStyleClass().add("base-pane");
Rectangle rect = new Rectangle();
rect.setHeight(20);
rect.setFill(Color.GREEN);
rect.widthProperty().bind(life.multiply(4));
basePane.getChildren().add(rect);
root.getChildren().add(createSolutionPane("Dynamic rectangle on pane", basePane));
// Solution 4: Dynamically-styled pane:
Pane dynamicPane = new Pane();
dynamicPane.setMinSize(400, 20);
dynamicPane.setMaxSize(400, 20);
dynamicPane.getStyleClass().add("dynamic-pane");
// make background insets depend on the property:
dynamicPane.styleProperty().bind(life.multiply(4).asString("-fx-background-insets: 0, 0 0 0 %f"));
root.getChildren().add(createSolutionPane("Dynamically styled pane", dynamicPane));
// Solution 5: Progress bar:
ProgressBar progressBar = new ProgressBar();
progressBar.setPrefSize(400, 20);
progressBar.progressProperty().bind(life.divide(100));
root.getChildren().add(createSolutionPane("Progress bar", progressBar));
root.getChildren().add(startButton);
Scene scene = new Scene(root);
scene.getStylesheets().add("two-colored-rectangle.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Node createSolutionPane(String title, Node content) {
VBox vbox = new VBox(new Label(title), content);
vbox.getStyleClass().add("solution-pane");
return vbox ;
}
public static void main(String[] args) {
launch(args);
}
}
和样式表 ( two-colored-rectangle.css
):
.root {
-fx-padding: 20 ;
-fx-alignment: center ;
}
.base-pane {
-fx-background-color: gray ;
}
.dynamic-pane {
-fx-background-color: green, gray ;
}
.solution-pane {
-fx-spacing: 5 ;
-fx-padding: 10 ;
}
.progress-bar {
-fx-accent: green ;
-fx-control-inner-background: gray ;
}
这可以使用LinearGradient
作为background
的填充来完成:
Region rect = new Region();
rect.setMaxSize(100, 20);
rect.setPrefSize(100, 20);
法典
rect.setBackground(new Background(new BackgroundFill(new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE,
new Stop(0.3, Color.GREEN),
new Stop(0.3, Color.RED)
), CornerRadii.EMPTY, Insets.EMPTY)));
.CSS
或者,您也可以使用 CSS 执行此操作:
rect.setId("myrect");
#myrect {
-fx-background-color: linear-gradient(to right, green 30%, red 30%);
}
两个版本都用绿色填充Rectangle
的前 30%,其余部分用红色(水平)填充。
请注意,应首选James_D的解决方案。这只是为了完整起见。
LinearGradient
扩展Paint
,因此您也可以将其分配给Rectangle
(或任何其他Shape
)的fill
属性。
从您的问题陈述中,我相信您上面问题的字面答案必须是"否",您不能用两种不同的颜色填充矩形的背景。它必须是其中之一。
但是为了实现你的问题中隐含的目标,(来自James_D的评论)你可以用你的第一种颜色画一个矩形,然后逐渐用第二个矩形覆盖它。或者,您可以绘制两个单独的矩形,每个矩形具有不同的颜色,每个矩形的宽度将一起填充整个条形。因此,起初,最右边的矩形将 100% 填充条形图,最左边的矩形将为 0%。然后每个的大小都会改变,右边是 99%,左边是 1%。等等。
JavaFX 矩形类