0

I need to draw a donut shape using JavaFX's GraphicsContext - a filled circle with a hole in the center, to clarify.

I have been searching and I can't find any examples online.

I think you'd use the fillarc function, but I do not understand it. There are no examples that I could find, and the docs do not help much. (What is arcExtent? All the docs say is that it's the extent of the arc...)

I don't want to fill two overlapping circles, because I want to keep the center transparent while drawing. (I have already drawn stuff underneath, I can't interfere with it)

MCMastery
  • 3,099
  • 2
  • 20
  • 43

1 Answers1

3

Here are a couple of sample solutions, one uses shape subtraction for circles, another uses an Arc. Both examples use the scene graph for drawing.

sample

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class DonutHole extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        // donut by shape subtraction.
        Circle whole = new Circle(20, 20, 20);
        Circle inside = new Circle(20, 20, 10);
        Shape donutShape = Shape.subtract(whole, inside);
        donutShape.setFill(Color.BLUE);

        // donut by arc.
        Arc donutArc = new Arc(60, 20, 10, 10, 0, 360);
        donutArc.setStrokeWidth(10);
        donutArc.setStrokeType(StrokeType.OUTSIDE);
        donutArc.setStroke(Color.RED);
        donutArc.setStrokeLineCap(StrokeLineCap.BUTT);
        donutArc.setFill(null);

        Scene scene = new Scene(new Group(donutShape, donutArc), Color.PALEGREEN);
        stage.setScene(scene);
        stage.show();
    }

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

An alternate solution could also use a Path with arc and line segments, but I don't show that here. If you wanted a 3D donut, you could create a Torus.


Here is another example which uses fillArc in a GraphicsContext.

fill

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class DonutHoleGraphics extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Canvas canvas = new Canvas(40, 40);

        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.setLineWidth(10);
        gc.setStroke(Color.YELLOW);
        gc.setLineCap(StrokeLineCap.BUTT);
        gc.strokeArc(5, 5, 30, 30, 0, 360, ArcType.OPEN);

        Scene scene = new Scene(new Group(canvas), Color.PALEGREEN);
        stage.setScene(scene);
        stage.show();
    }

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

Related:

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • Thank you! However, I do need to use `GraphicsContext`... I don't see any method for filling a given shape, also I don't see how, when stroking an arc (for your second method) I can set a thickness using `GraphicsContext` – MCMastery Jul 28 '17 at 21:29
  • Actually, I found it: `ctx.setLineWidth`. Thanks! I used the second method – MCMastery Jul 28 '17 at 21:34