Java Code Examples for javafx.scene.shape.Shape#subtract()

The following examples show how to use javafx.scene.shape.Shape#subtract() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Undecorator.java    From DevToolBox with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Compute the needed clip for stage's shadow border
 *
 * @param newBounds
 * @param shadowVisible
 */
void setShadowClip(Bounds newBounds) {
    external.relocate(
            newBounds.getMinX() - SHADOW_WIDTH,
            newBounds.getMinY() - SHADOW_WIDTH
    );
    internal.setX(SHADOW_WIDTH);
    internal.setY(SHADOW_WIDTH);
    internal.setWidth(newBounds.getWidth());
    internal.setHeight(newBounds.getHeight());
    internal.setArcWidth(shadowRectangle.getArcWidth());    // shadowRectangle CSS cannot be applied on this
    internal.setArcHeight(shadowRectangle.getArcHeight());

    external.setWidth(newBounds.getWidth() + SHADOW_WIDTH * 2);
    external.setHeight(newBounds.getHeight() + SHADOW_WIDTH * 2);
    Shape clip = Shape.subtract(external, internal);
    shadowRectangle.setClip(clip);

}
 
Example 2
Source File: AbstractInterpolator.java    From gef with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Adjusts the curveClip so that the curve node does not paint through the
 * given decoration.
 *
 * @param curveShape
 *            A shape describing the {@link ICurve} geometry, which is used
 *            for clipping.
 *
 * @param curveClip
 *            A shape that represents the clip of the curve node,
 *            interpreted in scene coordinates.
 * @param decoration
 *            The decoration to clip the curve node from.
 * @return A shape representing the resulting clip, interpreted in scene
 *         coordinates.
 */
protected Shape clipAtDecoration(Shape curveShape, Shape curveClip,
		Shape decoration) {
	// first intersect curve shape with decoration layout bounds,
	// then subtract the curve shape from the result, and the decoration
	// from that
	Path decorationShapeBounds = new Path(
			Geometry2Shape.toPathElements(NodeUtils
					.localToScene(decoration,
							NodeUtils.getShapeBounds(decoration))
					.toPath()));
	decorationShapeBounds.setFill(Color.RED);
	Shape clip = Shape.intersect(decorationShapeBounds, curveShape);
	clip = Shape.subtract(clip, decoration);
	clip = Shape.subtract(curveClip, clip);
	return clip;
}
 
Example 3
Source File: FarCry4Loading.java    From FXTutorials with MIT License 6 votes vote down vote up
public LoadingCircle() {
    Circle circle = new Circle(20);
    circle.setFill(null);
    circle.setStroke(Color.WHITE);
    circle.setStrokeWidth(2);

    Rectangle rect = new Rectangle(20, 20);

    Shape shape = Shape.subtract(circle, rect);
    shape.setFill(Color.WHITE);

    getChildren().add(shape);

    animation = new RotateTransition(Duration.seconds(2.5), this);
    animation.setByAngle(-360);
    animation.setInterpolator(Interpolator.LINEAR);
    animation.setCycleCount(Animation.INDEFINITE);
    animation.play();
}
 
Example 4
Source File: MKXMenuApp.java    From FXTutorials with MIT License 6 votes vote down vote up
public TriCircle() {
    Shape shape1 = Shape.subtract(new Circle(5), new Circle(2));
    shape1.setFill(Color.WHITE);

    Shape shape2 = Shape.subtract(new Circle(5), new Circle(2));
    shape2.setFill(Color.WHITE);
    shape2.setTranslateX(5);

    Shape shape3 = Shape.subtract(new Circle(5), new Circle(2));
    shape3.setFill(Color.WHITE);
    shape3.setTranslateX(2.5);
    shape3.setTranslateY(-5);

    getChildren().addAll(shape1, shape2, shape3);

    setEffect(new GaussianBlur(2));
}
 
Example 5
Source File: Text3DHelper.java    From FXyzLib with GNU General Public License v3.0 6 votes vote down vote up
public Text3DHelper(String text, String font, int size){
    this.text=text;
    list=new ArrayList<>();
    
    Text textNode = new Text(text);
    textNode.setFont(new Font(font,size));
    
    // Convert Text to Path
    Path subtract = (Path)(Shape.subtract(textNode, new Rectangle(0, 0)));
    // Convert Path elements into lists of points defining the perimeter (exterior or interior)
    subtract.getElements().forEach(this::getPoints);
    
    // Group exterior polygons with their interior polygons
    polis.stream().filter(LineSegment::isHole).forEach(hole->{
        polis.stream().filter(poly->!poly.isHole())
                .filter(poly->!((Path)Shape.intersect(poly.getPath(), hole.getPath())).getElements().isEmpty())
                .filter(poly->poly.getPath().contains(new Point2D(hole.getOrigen().x,hole.getOrigen().y)))
                .forEach(poly->poly.addHole(hole));
    });        
    polis.removeIf(LineSegment::isHole);                
}
 
Example 6
Source File: MicroscopeView.java    From narjillos with MIT License 6 votes vote down vote up
public Node toNode() {
	Vector screenSize = viewport.getSizeSC();
	if (screenSize.equals(currentScreenSize))
		return microscope;

	currentScreenSize = screenSize;

	double minScreenSize = Math.min(screenSize.x, screenSize.y);
	double maxScreenSize = Math.max(screenSize.x, screenSize.y);

	// Leave an ample left/bottom black margin - otherwise, the background
	// will be visible for a moment while enlarging the window.
	Rectangle black = new Rectangle(-10, -10, maxScreenSize + 1000, maxScreenSize + 1000);

	Circle hole = new Circle(screenSize.x / 2, screenSize.y / 2, minScreenSize / 2.03);
	microscope = Shape.subtract(black, hole);
	microscope.setEffect(new BoxBlur(5, 5, 1));

	return microscope;
}
 
Example 7
Source File: Piece.java    From DevToolBox with GNU Lesser General Public License v2.1 5 votes vote down vote up
private Shape createPiece() {
    Shape shape = createPieceRectangle();
    if (hasRightTab) {
        shape = Shape.union(shape,
                createPieceTab(69.5f, 0f, 10f, 17.5f, 50f, -12.5f, 11.5f,
                        25f, 56.25f, -14f, 6.25f, 56.25f, 14f, 6.25f));
    }
    if (hasBottomTab) {
        shape = Shape.union(shape,
                createPieceTab(0f, 69.5f, 17.5f, 10f, -12.5f, 50f, 25f,
                        11f, -14f, 56.25f, 6.25f, 14f, 56.25f, 6.25f));
    }
    if (hasLeftTab) {
        shape = Shape.subtract(shape,
                createPieceTab(-31f, 0f, 10f, 17.5f, -50f, -12.5f, 11f,
                        25f, -43.75f, -14f, 6.25f, -43.75f, 14f, 6.25f));
    }
    if (hasTopTab) {
        shape = Shape.subtract(shape,
                createPieceTab(0f, -31f, 17.5f, 10f, -12.5f, -50f, 25f,
                        12.5f, -14f, -43.75f, 6.25f, 14f, -43.75f, 6.25f));
    }
    shape.setTranslateX(correctX);
    shape.setTranslateY(correctY);
    shape.setLayoutX(50f);
    shape.setLayoutY(50f);
    return shape;
}
 
Example 8
Source File: Piece.java    From DevToolBox with GNU Lesser General Public License v2.1 5 votes vote down vote up
private Shape createPieceTab(double eclipseCenterX, double eclipseCenterY, double eclipseRadiusX, double eclipseRadiusY,
        double rectangleX, double rectangleY, double rectangleWidth, double rectangleHeight,
        double circle1CenterX, double circle1CenterY, double circle1Radius,
        double circle2CenterX, double circle2CenterY, double circle2Radius) {
    Ellipse e = new Ellipse(eclipseCenterX, eclipseCenterY, eclipseRadiusX, eclipseRadiusY);
    Rectangle r = new Rectangle(rectangleX, rectangleY, rectangleWidth, rectangleHeight);
    Shape tab = Shape.union(e, r);
    Circle c1 = new Circle(circle1CenterX, circle1CenterY, circle1Radius);
    tab = Shape.subtract(tab, c1);
    Circle c2 = new Circle(circle2CenterX, circle2CenterY, circle2Radius);
    tab = Shape.subtract(tab, c2);
    return tab;
}
 
Example 9
Source File: Connect4App.java    From FXTutorials with MIT License 5 votes vote down vote up
private Shape makeGrid() {
    Shape shape = new Rectangle((COLUMNS + 1) * TILE_SIZE, (ROWS + 1) * TILE_SIZE);

    for (int y = 0; y < ROWS; y++) {
        for (int x = 0; x < COLUMNS; x++) {
            Circle circle = new Circle(TILE_SIZE / 2);
            circle.setCenterX(TILE_SIZE / 2);
            circle.setCenterY(TILE_SIZE / 2);
            circle.setTranslateX(x * (TILE_SIZE + 5) + TILE_SIZE / 4);
            circle.setTranslateY(y * (TILE_SIZE + 5) + TILE_SIZE / 4);

            shape = Shape.subtract(shape, circle);
        }
    }

    Light.Distant light = new Light.Distant();
    light.setAzimuth(45.0);
    light.setElevation(30.0);

    Lighting lighting = new Lighting();
    lighting.setLight(light);
    lighting.setSurfaceScale(5.0);

    shape.setFill(Color.BLUE);
    shape.setEffect(lighting);

    return shape;
}
 
Example 10
Source File: ShapeConverter.java    From Enzo with Apache License 2.0 5 votes vote down vote up
public static String shapeToSvgString(final Shape SHAPE) {
    final StringBuilder fxPath = new StringBuilder();
    if (Line.class.equals(SHAPE.getClass())) {
        fxPath.append(convertLine((Line) SHAPE));
    } else if (Arc.class.equals(SHAPE.getClass())) {
        fxPath.append(convertArc((Arc) SHAPE));
    } else if (QuadCurve.class.equals(SHAPE.getClass())) {
        fxPath.append(convertQuadCurve((QuadCurve) SHAPE));
    } else if (CubicCurve.class.equals(SHAPE.getClass())) {
        fxPath.append(convertCubicCurve((CubicCurve) SHAPE));
    } else if (Rectangle.class.equals(SHAPE.getClass())) {
        fxPath.append(convertRectangle((Rectangle) SHAPE));
    } else if (Circle.class.equals(SHAPE.getClass())) {
        fxPath.append(convertCircle((Circle) SHAPE));
    } else if (Ellipse.class.equals(SHAPE.getClass())) {
        fxPath.append(convertEllipse((Ellipse) SHAPE));
    } else if (Text.class.equals(SHAPE.getClass())) {
        Path path = (Path)(Shape.subtract(SHAPE, new Rectangle(0, 0)));
        fxPath.append(convertPath(path));
    } else if (Path.class.equals(SHAPE.getClass())) {
        fxPath.append(convertPath((Path) SHAPE));
    } else if (Polygon.class.equals(SHAPE.getClass())) {
        fxPath.append(convertPolygon((Polygon) SHAPE));
    } else if (Polyline.class.equals(SHAPE.getClass())) {
        fxPath.append(convertPolyline((Polyline) SHAPE));
    } else if (SVGPath.class.equals(SHAPE.getClass())) {
        fxPath.append(((SVGPath) SHAPE).getContent());
    }
    return fxPath.toString();
}
 
Example 11
Source File: WhiteSkin.java    From Medusa with Apache License 2.0 4 votes vote down vote up
@Override protected void resize() {
    double width  = gauge.getWidth() - gauge.getInsets().getLeft() - gauge.getInsets().getRight();
    double height = gauge.getHeight() - gauge.getInsets().getTop() - gauge.getInsets().getBottom();
    size          = width < height ? width : height;

    if (width > 0 && height > 0) {
        pane.setMaxSize(size, size);
        pane.relocate((width - size) * 0.5, (height - size) * 0.5);

        shadow.setRadius(size * 0.06);
        shadow.setOffsetX(size * 0.02);
        shadow.setOffsetY(size * 0.02);

        textShadow.setRadius(size * 0.0125);
        textShadow.setOffsetX(size * 0.00625);
        textShadow.setOffsetY(size * 0.00625);

        center = size * 0.5;

        valueText.setFont(Fonts.robotoBold(size * 0.20625));

        unitText.setFont(Fonts.robotoBold(size * 0.0875));

        Arc outerRing = new Arc(size * 0.5, size * 0.5,
                                size * 0.43125, size * 0.43125,
                                0, 360);
        outerRing.setFill(null);
        outerRing.setStroke(Color.WHITE);
        outerRing.setStrokeLineCap(StrokeLineCap.BUTT);
        outerRing.setStrokeWidth(size * 0.3);

        Arc innerRing = new Arc(size * 0.5, size * 0.5,
                                size * 0.43125, size * 0.43125,
                                0, 360);
        innerRing.setFill(null);
        innerRing.setStroke(Color.WHITE);
        innerRing.setStrokeLineCap(StrokeLineCap.BUTT);
        innerRing.setStrokeWidth(size * 0.1375);

        Shape shape = Shape.subtract(outerRing, innerRing);

        backgroundRing.setCenterX(center);
        backgroundRing.setCenterY(center);
        backgroundRing.setRadiusX(size * 0.43125);
        backgroundRing.setRadiusY(size * 0.43125);
        backgroundRing.setStrokeWidth(size * 0.1375);
        backgroundRing.setClip(shape);

        barBackground.setCenterX(center);
        barBackground.setCenterY(center);
        barBackground.setRadiusX(size * 0.43125);
        barBackground.setRadiusY(size * 0.43125);
        barBackground.setStrokeWidth(size * 0.1375);

        bar.setCenterX(center);
        bar.setCenterY(center);
        bar.setRadiusX(size * 0.43125);
        bar.setRadiusY(size * 0.43125);
        bar.setStrokeWidth(size * 0.1375);

        resizeValueText();
        resizeUnitText();
    }
}
 
Example 12
Source File: Regulator.java    From regulators with Apache License 2.0 4 votes vote down vote up
private void initGraphics() {
    dropShadow  = new DropShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), PREFERRED_WIDTH * 0.016, 0.0, 0, PREFERRED_WIDTH * 0.028);
    highlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    innerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    highlight.setInput(innerShadow);
    dropShadow.setInput(highlight);

    barArc = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, BAR_START_ANGLE, 0);
    barArc.setType(ArcType.OPEN);
    barArc.setStrokeLineCap(StrokeLineCap.ROUND);
    barArc.setFill(null);
    barArc.setStroke(barColor.get());

    double center = PREFERRED_WIDTH * 0.5;
    ring = Shape.subtract(new Circle(center, center, PREFERRED_WIDTH * 0.42),
                          new Circle(center, center, PREFERRED_WIDTH * 0.3));
    ring.setFill(color.get());
    ring.setEffect(dropShadow);

    mainCircle = new Circle();
    mainCircle.setFill(color.get().darker().darker());

    text = new Text(String.format(Locale.US, formatString, getTargetValue()));
    text.setFill(Color.WHITE);
    text.setTextOrigin(VPos.CENTER);

    indicatorRotate = new Rotate(-ANGLE_RANGE *  0.5, center, center);

    indicatorGlow        = new DropShadow(BlurType.TWO_PASS_BOX, getIndicatorColor(), PREFERRED_WIDTH * 0.02, 0.0, 0, 0);
    indicatorInnerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.5), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    indicatorHighlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.35), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    indicatorHighlight.setInput(indicatorInnerShadow);

    indicator = new Circle();
    indicator.setFill(color.get().darker());
    indicator.setStroke(color.get().darker().darker());
    indicator.setMouseTransparent(true);
    indicator.getTransforms().add(indicatorRotate);

    Group indicatorGroup = new Group(indicator);
    indicatorGroup.setEffect(indicatorHighlight);

    symbol = new Region();
    symbol.getStyleClass().setAll("symbol");
    symbol.setCacheHint(CacheHint.SPEED);

    icon = new FontIcon();
    icon.setTextOrigin(VPos.CENTER);

    iconPane = new StackPane(symbol, icon);

    pane = new Pane(barArc, ring, mainCircle, text, indicatorGroup, iconPane);
    pane.setPrefSize(PREFERRED_HEIGHT, PREFERRED_HEIGHT);
    pane.setBackground(new Background(new BackgroundFill(color.get().darker(), new CornerRadii(1024), Insets.EMPTY)));
    pane.setEffect(highlight);

    getChildren().setAll(pane);
}
 
Example 13
Source File: ColorRegulator.java    From regulators with Apache License 2.0 4 votes vote down vote up
private void initGraphics() {
    dropShadow  = new DropShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), PREFERRED_WIDTH * 0.016, 0.0, 0, PREFERRED_WIDTH * 0.028);
    highlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    innerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    highlight.setInput(innerShadow);
    dropShadow.setInput(highlight);

    Stop[] stops = { new Stop(0.0, Color.rgb(255,255,0)),
                     new Stop(0.125, Color.rgb(255,0,0)),
                     new Stop(0.375, Color.rgb(255,0,255)),
                     new Stop(0.5, Color.rgb(0,0,255)),
                     new Stop(0.625, Color.rgb(0,255,255)),
                     new Stop(0.875, Color.rgb(0,255,0)),
                     new Stop(1.0, Color.rgb(255,255,0)) };

    List<Stop> reorderedStops = reorderStops(stops);

    gradientLookup = new GradientLookup(stops);

    barGradient = new ConicalGradient(reorderedStops);
    barArc = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, BAR_START_ANGLE, 0);
    barArc.setType(ArcType.OPEN);
    barArc.setStrokeLineCap(StrokeLineCap.ROUND);
    barArc.setFill(null);
    barArc.setStroke(barGradient.getImagePattern(new Rectangle(0, 0, PREFERRED_WIDTH, PREFERRED_HEIGHT)));

    buttonOn = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, -125, 34.75);
    buttonOn.setFill(null);
    buttonOn.setStroke(color.get());
    buttonOn.setStrokeLineCap(StrokeLineCap.BUTT);
    buttonOn.setStrokeWidth(PREFERRED_WIDTH * 0.072);
    buttonOn.setEffect(dropShadow);

    buttonOff = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, -89.75, 34.75);
    buttonOff.setFill(null);
    buttonOff.setStroke(color.get());
    buttonOff.setStrokeLineCap(StrokeLineCap.BUTT);
    buttonOff.setStrokeWidth(PREFERRED_WIDTH * 0.072);
    buttonOff.setEffect(dropShadow);

    double center = PREFERRED_WIDTH * 0.5;
    ring = Shape.subtract(new Circle(center, center, PREFERRED_WIDTH * 0.42),
                          new Circle(center, center, PREFERRED_WIDTH * 0.3));
    ring.setFill(color.get());
    ring.setEffect(highlight);

    mainCircle = new Circle();
    mainCircle.setFill(color.get().darker().darker());

    textOn = new Text("ON");
    textOn.setFill(textColor.get());
    textOn.setTextOrigin(VPos.CENTER);
    textOn.setMouseTransparent(true);
    textOn.setRotate(17);

    textOff = new Text("OFF");
    textOff.setFill(textColor.get());
    textOff.setTextOrigin(VPos.CENTER);
    textOff.setMouseTransparent(true);
    textOff.setRotate(-17);

    indicatorRotate = new Rotate(-ANGLE_RANGE *  0.5, center, center);

    indicatorGlow        = new DropShadow(BlurType.TWO_PASS_BOX, getIndicatorColor(), PREFERRED_WIDTH * 0.02, 0.0, 0, 0);
    indicatorInnerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.5), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    indicatorHighlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.35), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    indicatorHighlight.setInput(indicatorInnerShadow);

    indicator = new Circle();
    indicator.setFill(color.get().darker());
    indicator.setStroke(color.get().darker().darker());
    indicator.setMouseTransparent(true);
    indicator.getTransforms().add(indicatorRotate);

    Group indicatorGroup = new Group(indicator);
    indicatorGroup.setEffect(indicatorHighlight);

    innerRing = Shape.subtract(new Circle(center, center, PREFERRED_WIDTH * 0.24),
                               new Circle(center, center, PREFERRED_WIDTH * 0.2));
    innerRing.setFill(color.get());

    currentColorCircle = new Circle();
    currentColorCircle.setFill(targetColor.get());
    currentColorCircle.setVisible(isOn());

    pane = new Pane(barArc, ring, mainCircle, currentColorCircle, innerRing, indicatorGroup, buttonOn, textOn, buttonOff, textOff);
    pane.setPrefSize(PREFERRED_HEIGHT, PREFERRED_HEIGHT);
    pane.setBackground(new Background(new BackgroundFill(color.get().darker(), new CornerRadii(1024), Insets.EMPTY)));
    pane.setEffect(highlight);

    getChildren().setAll(pane);
}
 
Example 14
Source File: FeedbackRegulator.java    From regulators with Apache License 2.0 4 votes vote down vote up
private void initGraphics() {
    dropShadow  = new DropShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.65), PREFERRED_WIDTH * 0.016, 0.0, 0, PREFERRED_WIDTH * 0.028);
    highlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    innerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.2), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    highlight.setInput(innerShadow);
    dropShadow.setInput(highlight);

    Stop[] stops = {
        new Stop(0.0, Color.rgb(135, 255, 190)),
        new Stop(0.125, Color.rgb(254, 190, 106)),
        new Stop(0.389, Color.rgb(252, 84, 68)),
        new Stop(0.611, Color.rgb(99, 195, 255)),
        new Stop(1.0, Color.rgb(125, 255, 190))
    };

    barGradient = new ConicalGradient(stops);

    barArc = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, BAR_START_ANGLE, 0);
    barArc.setType(ArcType.OPEN);
    barArc.setStrokeLineCap(StrokeLineCap.ROUND);
    barArc.setFill(null);
    barArc.setStroke(barGradient.getImagePattern(new Rectangle(0, 0, PREFERRED_WIDTH, PREFERRED_HEIGHT)));

    overlayBarArc = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.46, PREFERRED_HEIGHT * 0.46, BAR_START_ANGLE, 0);
    overlayBarArc.setType(ArcType.OPEN);
    overlayBarArc.setStrokeLineCap(StrokeLineCap.ROUND);
    overlayBarArc.setFill(null);
    overlayBarArc.setStroke(Color.rgb(0, 0, 0, 0.3));
    overlayBarArc.setVisible((int) targetValue.get() != (int) currentValue.get());

    double center = PREFERRED_WIDTH * 0.5;
    ring = Shape.subtract(new Circle(center, center, PREFERRED_WIDTH * 0.42),
                          new Circle(center, center, PREFERRED_WIDTH * 0.3));
    ring.setFill(color.get());
    ring.setEffect(dropShadow);

    mainCircle = new Circle();
    mainCircle.setFill(color.get().darker().darker());

    text = new Text(String.format(Locale.US, formatString, currentValue.get()));
    text.setFill(textColor.get());
    text.setTextOrigin(VPos.CENTER);

    targetText = new Text(String.format(Locale.US, formatString, targetValue.get()));
    targetText.setFill(textColor.get().darker());
    targetText.setTextOrigin(VPos.CENTER);
    targetText.setVisible((int) targetValue.get() != (int) currentValue.get());

    indicatorRotate = new Rotate(-ANGLE_RANGE *  0.5, center, center);

    indicatorGlow        = new DropShadow(BlurType.TWO_PASS_BOX, getIndicatorColor(), PREFERRED_WIDTH * 0.02, 0.0, 0, 0);
    indicatorInnerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.5), PREFERRED_WIDTH * 0.008, 0.0, 0, PREFERRED_WIDTH * 0.008);
    indicatorHighlight   = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(255, 255, 255, 0.35), PREFERRED_WIDTH * 0.008, 0.0, 0, -PREFERRED_WIDTH * 0.008);
    indicatorHighlight.setInput(indicatorInnerShadow);

    indicator = new Circle();
    indicator.setFill(color.get().darker());
    indicator.setStroke(color.get().darker().darker());
    indicator.setMouseTransparent(true);
    indicator.getTransforms().add(indicatorRotate);

    Group indicatorGroup = new Group(indicator);
    indicatorGroup.setEffect(indicatorHighlight);

    symbol = new Region();
    symbol.getStyleClass().setAll("symbol");
    symbol.setCacheHint(CacheHint.SPEED);

    icon = new FontIcon();
    icon.setTextOrigin(VPos.CENTER);

    iconPane = new StackPane(symbol, icon);

    pane = new Pane(barArc, overlayBarArc, ring, mainCircle, text, targetText, indicatorGroup, iconPane);
    pane.setPrefSize(PREFERRED_HEIGHT, PREFERRED_HEIGHT);
    pane.setBackground(new Background(new BackgroundFill(color.get().darker(), new CornerRadii(1024), Insets.EMPTY)));
    pane.setEffect(highlight);

    getChildren().setAll(pane);
}