Overall, I like the group based approach you outlined in your question. It is unfortunate that it does not fit your particular situation, but for others who come across this question, it may be the preferred solution for their application.
You could apply a DropShadow effect to your PolyLine to generate the border color. This will end up with slightly rounded edges for corners, which may or may not be what you wish.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;
public class Polyanna extends Application {
@Override
public void start(Stage stage) {
Polyline polyline = new Polyline();
polyline.getPoints().addAll(50.0, 50.0,
200.0, 100.0,
100.0, 200.0
);
polyline.setStrokeWidth(8);
DropShadow borderEffect = new DropShadow(
BlurType.THREE_PASS_BOX, Color.BLUE, 2, 1, 0, 0
);
polyline.setEffect(borderEffect);
stage.setScene(
new Scene(
new Group(polyline),
250, 250
)
);
stage.show();
}
public static void main(String\[\] args) {
launch(args);
}
}
An alternate option is to draw a Polygon with a fill and stroke rather than a PolyLine. You could write a routine which takes an array of points for a Polyline and generates a matching array of points for a Polygon from that input array (with a bit of work ;-)
You can use shape intersection capabilities to create an arbitrary shape that you can fill and stroke to possibly end up with the easiest way to get something closest to what you wish. With this approach you have programmatic control over things like line caps, mitering and line join settings for the stroke of the border color.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
public class PolyIntersect extends Application {
private static final double W = 250;
private static final double H = 250;
@Override
public void start(Stage stage) {
Polyline polyline = new Polyline();
polyline.getPoints().addAll(50.0, 50.0,
200.0, 100.0,
100.0, 200.0
);
polyline.setStrokeWidth(8);
Rectangle bg = new Rectangle(0, 0, W, H);
Shape shape = Shape.intersect(bg, polyline);
shape.setFill(Color.BLACK);
shape.setStroke(Color.BLUE);
shape.setStrokeType(StrokeType.OUTSIDE);
shape.setStrokeWidth(2);
stage.setScene(
new Scene(
new Group(shape),
W, H
)
);
stage.setResizable(false);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}