线性梯度的边界计算考虑了父级的边界,而不是应用它的节点

Linear gradient's bounds computation takes parent's bounds in account, not the node on which it is applied on

我想在一条线上添加一个线性渐变(宽度方面,即横跨它的笔画宽度)。此行是组节点的子节点。当我在线上应用线性渐变时,色标是使用组的边界而不是线边界计算的。 在我下面的代码中,线性渐变在按长度添加时会正确显示,即 "to bottom",但在按宽度添加时不会显示,即 "to right"。 谁能告诉我可以解决这个问题的方法是什么? 这里是 SSCCE

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Test extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
    Group group = new Group();
    primaryStage.setScene(new Scene(group, 200, 350));

    Line line = new Line(100, 50, 100, 300);
    group.getChildren().add(line);
    line.setStyle("-fx-stroke-width:3em; -fx-stroke:linear-gradient(to right, red, green);");
    //line.setStyle("-fx-stroke-width:3em; -fx-stroke:linear-gradient(to bottom, red, green);");

    primaryStage.show();
}

public static void main(String[] args) {
    launch();
}

}

它采用组边界的假设是不正确的。事实上,它正在跨越这条线。这就是问题所在。

如果您转到 com.sun.prism.j2d.J2DPrismGraphics,您会看到带有渐变的形状,这就是 fill() 的完成方式:

void fill(java.awt.Shape shape) {
    if (paintWasProportional) {
        if (nodeBounds != null) {
            g2d.setPaint(toJ2DPaint(paint, nodeBounds));
        } else {
            g2d.setPaint(toJ2DPaint(paint, shape.getBounds2D()));
        }
    }
    g2d.fill(shape);
}

paintWasProportional 检查给了我一个提示,让我从另一个角度解决你的问题。

让我们从使用 LinearGradient 对象开始,通过代码而不是使用 CSS。那么这将是您的起点:

@Override
public void start(Stage primaryStage) throws Exception {
    Group group = new Group();
    primaryStage.setScene(new Scene(group, 200, 350));

    Line line = new Line(100, 50, 100, 300);
    LinearGradient linearGradient = new LinearGradient(0d, 0d, 0d, 1d, true,
      CycleMethod.NO_CYCLE, new Stop(0,Color.RED),new Stop(1,Color.GREEN));
line.setStrokeWidth(36); // 3em
    line.setStroke(linearGradient);
    group.getChildren().add(line);
    primaryStage.show();
}

与预期结果(黑线仅供参考):

现在,为了获得渐变 to right,让我们改变创建渐变的方式,使用 非比例 一个:

LinearGradient linearGradient = new LinearGradient(0d, 50d, 0d, 300d,
       false, CycleMethod.REFLECT,new Stop(0,Color.RED), new Stop(1,Color.GREEN));   

这将有相同的结果。

如果你想改变方向,这就是你需要的:

LinearGradient linearGradient = new LinearGradient(100-18d, 0d, 100+18d, 0d,
 false, CycleMethod.REFLECT,new Stop(0,Color.RED), new Stop(1,Color.GREEN));

结果如下:

请注意,您现在也可以尝试通过 CSS 完成此操作。