Javafx线性梯度重复似乎反映了颜色而不是重复。
我写了一个简单的应用程序,以显示我在使用线性渐变和重复时在自定义节点(StackPane)上的应用程序中创建条带图案时看到的内容。在我的应用程序中,它作为叠加添加到XYChart并且它们的高度变化。使用Rectangle效果不佳,这就是我使用Stackpane并在其上设置样式而不是以编程方式创建LinearGradient的原因。颜色列表是动态的,并且在应用程序中的大小不同。问题是线性渐变翻转列表并反映每次重复的颜色而不是重复。
这个链接描述了一个类似的问题,但只是添加无休止的停止似乎是一个混乱的解决方案,我的问题,添加颜色一次并重复将更好。
linear gradient repeat on css for javafx
java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
List<Color> colors = Arrays.asList( Color.RED,Color.BLUE,Color.YELLOW,Color.GREEN);
StackPane stackPane = new StackPane();
stackPane.setStyle(getLinearGradientStyle(colors));
root.setCenter(stackPane);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e) {
e.printStackTrace();
}
}
private String getLinearGradientStyle(List<Color> colors) {
StringBuilder stringBuilder = new StringBuilder("-fx-background-color: linear-gradient(from 0px 0px to 10px 10px, repeat,");
for (int i = 0; i < colors.size(); i++) {
stringBuilder.append("rgb(")
.append((int) (colors.get(i).getRed() * 255)).append(",")
.append((int) (colors.get(i).getGreen() * 255)).append(",")
.append((int) (colors.get(i).getBlue() * 255))
.append(")")
.append(" ").append(getPercentage(i+1, colors.size()+1) );
if (i < colors.size() - 1) {
stringBuilder.append(",");
}
}
stringBuilder.append(");");
System.out.println("Main.getLinearGradientStyle():"+stringBuilder);
return stringBuilder.toString();
}
private String getPercentage(float i, int size) {
return (((1.0f / size) * 100 )*i)+ "%";
}
public static void main(String[] args) {
launch(args);
}
这是使用重复线性渐变的CSS3示例:
https://tympanus.net/codrops/css_reference/repeating-linear-gradient/
向下滚动到下面的文本:将创建一个条纹背景,其中每个线性渐变是一个三条纹渐变,无限重复(这是示例)
我的例子使用的是对角线模式,这是我需要的,但上面的例子显示了我想看到的正常重复颜色与正常css中的反射。
谢谢你的帮助
这看起来像一个bug。如果您运行以下示例(将CSS移动到文件中):
main.Java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
Region region = new Region();
region.backgroundProperty().addListener((obs, ov, nv) ->
System.out.println(nv.getFills().get(0).getFill()));
Scene scene = new Scene(region, 500, 300);
scene.getStylesheets().add("Main.css");
primaryStage.setScene(scene);
primaryStage.show();
}
}
的main.css
.root {
-fx-background-color: linear-gradient(from 0px 0px to 10px 10px, repeat, red 20%, blue 40%, yellow 60%, green 80%);
}
你会看到以下打印出来:
linear-gradient(from 0.0px 0.0px to 10.0px 10.0px, reflect, 0xff0000ff 0.0%, 0xff0000ff 20.0%, 0x0000ffff 40.0%, 0xffff00ff 60.0%, 0x008000ff 80.0%, 0x008000ff 100.0%)
正如您所看到的,尽管在CSS中使用“重复”,创建的LinearGradient
使用“反射”。
您自己可能无法对此错误做任何事情,但如果您不介意在代码中设置背景(或者甚至可能是FXML),那么以下内容应该按照您的意愿执行:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
LinearGradient gradient = new LinearGradient(0, 0, 10, 10, false, CycleMethod.REPEAT,
new Stop(0.2, Color.RED),
new Stop(0.4, Color.BLUE),
new Stop(0.6, Color.YELLOW),
new Stop(0.8, Color.GREEN)
);
Region region = new Region();
region.setBackground(new Background(new BackgroundFill(gradient, null, null)));
Scene scene = new Scene(region, 500, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
}
您可以将LinearGradient
的创建移动到一个采用任意数量的Color
s的方法,就像您目前正在做的那样。
如果你有兴趣,我相信这个bug位于javafx.css.CssParser
线1872
附近(在JavaFX 12中):
CycleMethod cycleMethod = CycleMethod.NO_CYCLE;
if ("reflect".equalsIgnoreCase(arg.token.getText())) {
cycleMethod = CycleMethod.REFLECT;
prev = arg;
arg = arg.nextArg;
} else if ("repeat".equalsIgnoreCase(arg.token.getText())) {
cycleMethod = CycleMethod.REFLECT;
prev = arg;
arg = arg.nextArg;
}
正如你所看到的,当文本等于CycleMethod
时,它错误地将REFLECT
设置为"repeat
“。
已提交错误报告:JDK-8222222(GitHub #437)。修复版本:openjfx13。