1

How can I use lineargradient for Line in Javafx?
I tried this:

LinearGradient lg = new LinearGradient(...);
line.setFill(lg);  
....

It doesn't work.

Cauchy Schwarz
  • 747
  • 3
  • 10
  • 27
  • Check this [answer](http://stackoverflow.com/a/28033436/3956070) and this [one](http://stackoverflow.com/a/28765099/3956070). – José Pereda Nov 18 '15 at 08:57
  • I just want to draw a line, its color varies smoothly from some color(like red) at one end to another(like blue) at the other end. The line is neither vertical nor horizontal, its direction is arbitrary. – Cauchy Schwarz Nov 18 '15 at 09:15
  • 1
    Based on those answers, you will be able to do it, but it needs some maths, to generate the gradient based on the line direction – José Pereda Nov 18 '15 at 09:22
  • Do you mean that I create a horizontal/vertical line first, and then try to rotate and translate it to the right position? If so, I know how to solve this problem. What's more, can I set the parameters for _LinearGradient()_ to get the same effect? – Cauchy Schwarz Nov 18 '15 at 10:01
  • No, rotation doesn't work. For any given line between `(x1,y1)` and `(x2, y2)` you have to set the gradient based on those parameters. – José Pereda Nov 18 '15 at 10:04
  • I am sorry that I don't much about the meaning of parameters for _LinearGradient(double startX, double startY, double endX, double endY, boolean proportional, CycleMethod cycleMethod, Stop... stops)_, especially startX, startY, endX, endY. Where can I find detailed description about it? – Cauchy Schwarz Nov 18 '15 at 10:12
  • I don't understand why _LinearGradient(x1, y1, x2, y2, ...)_ doesn't work. Also, _LinearGradient(x1/width, y1/height, x2/width, y2/height, ...)_ doesn't work. – Cauchy Schwarz Nov 18 '15 at 10:17

2 Answers2

1

Use this

line.setStyle("-fx-background-color: linear-gradient(to right, #color_1, #color_2);");
Collins Abitekaniza
  • 4,496
  • 2
  • 28
  • 43
  • First I don't know if this work for lines at any direciton. Second, I need to specify the colors at run time, so I need to generate the string dynamically? – Cauchy Schwarz Nov 18 '15 at 10:24
1

Based on this answer, you need to specify the gradient on absolute coordinates.

Something like this will work for any given ones:

LinearGradient linearGradient = new LinearGradient(x1, y1, x2, y2, false, CycleMethod.REFLECT, new Stop(0,Color.RED),new Stop(1,Color.GREEN));
line.setStroke(linearGradient);

Based on this answer, you can create a simple app to test it how it works when you move the anchor nodes around the scene:

private final DoubleProperty x1 = new SimpleDoubleProperty();
public final double getX1() { return x1.get(); }
public final void setX1(double value) { x1.set(value); }
public final DoubleProperty x1Property() { return x1; }

private final DoubleProperty x2 = new SimpleDoubleProperty();
public final double getX2() { return x2.get(); }
public final void setX2(double value) { x2.set(value); }
public final DoubleProperty x2Property() { return x2; }

private final DoubleProperty y1 = new SimpleDoubleProperty();
public final double getY1() { return y1.get(); }
public final void setY1(double value) { y1.set(value); }
public final DoubleProperty y1Property() { return y1; }

private final DoubleProperty y2 = new SimpleDoubleProperty();
public final double getY2() { return y2.get(); }
public final void setY2(double value) { y2.set(value); }
public final DoubleProperty y2Property() { return y2; }

private Line line;

@Override
public void start(Stage primaryStage) {
    Group group = new Group();
    primaryStage.setScene(new Scene(group, 400, 400));

    x1.set(100);
    y1.set(50);
    x2.set(200);
    y2.set(300);

    line = new Line(x1.get(), y1.get(), x2.get(), y2.get());
    line.startXProperty().bind(x1);
    line.startYProperty().bind(y1);
    line.endXProperty().bind(x2);
    line.endYProperty().bind(y2);
    line.setStrokeWidth(12); 
    line.setMouseTransparent(true);

    Anchor start = new Anchor(Color.BLUE, x1, y1);
    Anchor end = new Anchor(Color.YELLOW, x2, y2);

    group.getChildren().setAll(line, start, end);

    x1Property().addListener(o -> updateLine());
    x2Property().addListener(o -> updateLine());
    y1Property().addListener(o -> updateLine());
    y2Property().addListener(o -> updateLine());
    updateLine();

    primaryStage.show();
}

private void updateLine() {
    LinearGradient linearGradient = new LinearGradient(x1.get(), y1.get(), x2.get(), y2.get(), false, CycleMethod.REFLECT, new Stop(0,Color.RED),new Stop(1,Color.GREEN));
    line.setStroke(linearGradient);
}

private class Anchor extends Circle { 

    Anchor(Color color, DoubleProperty x, DoubleProperty y) {
        super(x.get(), y.get(), 10);
        setFill(color.deriveColor(1, 1, 1, 0.5));
        setStroke(color);
        setStrokeWidth(2);
        setStrokeType(StrokeType.OUTSIDE);

        x.bind(centerXProperty());
        y.bind(centerYProperty());
        enableDrag();
    }

    // make a node movable by dragging it around with the mouse.
    private void enableDrag() {
        final Delta dragDelta = new Delta();
        setOnMousePressed(mouseEvent -> {
            // record a delta distance for the drag and drop operation.
            dragDelta.x = getCenterX() - mouseEvent.getX();
            dragDelta.y = getCenterY() - mouseEvent.getY();
            getScene().setCursor(Cursor.MOVE);
        });
        setOnMouseReleased(mouseEvent -> {
            getScene().setCursor(Cursor.HAND);
        });
        setOnMouseDragged(mouseEvent -> {
            double newX = mouseEvent.getX() + dragDelta.x;
            if (newX > 0 && newX < getScene().getWidth()) {
                setCenterX(newX);
            }
            double newY = mouseEvent.getY() + dragDelta.y;
            if (newY > 0 && newY < getScene().getHeight()) {
                setCenterY(newY);
            }
        });
        setOnMouseEntered(mouseEvent -> {
            if (!mouseEvent.isPrimaryButtonDown()) {
                getScene().setCursor(Cursor.HAND);
            }
        });
        setOnMouseExited(mouseEvent -> {
            if (!mouseEvent.isPrimaryButtonDown()) {
                getScene().setCursor(Cursor.DEFAULT);
            }
        });
    }

    // records relative x and y co-ordinates.
    private class Delta { double x, y; }
}  

Linear Gradient

Community
  • 1
  • 1
José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • You are really helpful!!! This is exactly what I want. I shouldn't use _setFill()_ method. You said that "it needs some maths", what does that mean? – Cauchy Schwarz Nov 18 '15 at 11:07
  • I meant the gradient has to be evaluated on any line coordinates change. Using absolute coordinates doesn't requiere further computations after all. If the answer is helpful for you, mark it as accepted, as it will help others as well. – José Pereda Nov 18 '15 at 11:09