JavaFX线性梯度重复行为

ric*_*bby 3 javafx javafx-8

Javafx线性渐变重复似乎反映了颜色而不是重复。

我编写了一个简单的应用程序,以显示在自定义节点(StackPane)上的应用程序中使用线性渐变和重复创建条纹图案时看到的内容。在我的应用程序中,这是作为叠加层添加到XYChart中的,它们的高度各不相同。使用Rectangle效果不佳,这就是为什么我使用Stackpane并在其上设置样式而不是通过编程方式创建LinearGradient的原因。颜色列表是动态的,并且在应用程序中大小会有所不同。问题是线性渐变翻转列表并在每次重复而不是仅重复时反映颜色的方式。

该链接描述了一个类似的问题,但只是添加无休止的停顿似乎对我的问题来说似乎是一个混乱的解决方案,所以最好只添加一次颜色并重复一次。

JavaFX在CSS上重复线性渐变

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);

}
Run Code Online (Sandbox Code Playgroud)

这是一个使用重复线性梯度的CSS3示例:

https://tympanus.net/codrops/css_reference/repeating-linear-gradient/

向下滚动至以下文本:将创建条纹背景,其中每个线性渐变均为三条纹渐变,并无限重复(此示例)

我的示例使用了我所需要的对角线图案,但是上面的示例显示了我希望看到的纯色重复颜色而在普通CSS中没有反射。

谢谢你的帮助

Sla*_*law 5

这看起来像个错误。如果运行以下示例(将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();
    }

}
Run Code Online (Sandbox Code Playgroud)

Main.css

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();
    }

}
Run Code Online (Sandbox Code Playgroud)

您将看到以下内容打印出来:

.root {
    -fx-background-color: linear-gradient(from 0px 0px to 10px 10px, repeat, red 20%, blue 40%, yellow 60%, green 80%);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,尽管在CSS中使用了“ repeat”,但LinearGradient创建的内容还是使用了“ reflect”。

您自己对此错误可能无能为力,但是,如果您不介意在代码(或什至甚至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();
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以将的创建移动LinearGradient到需要任意数量Colors的方法中,就像您当前正在做的那样。


如果您有兴趣,我相信该错误位于代码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;
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它错误地将CycleMethod,以REFLECT文本为等于"repeat”。

已提交错误报告:JDK-8222222(GitHub #437)。修复版本:openjfx13