Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a semi ring - JavaFX

I would like to know how to draw a semi circle in JavaFX. I tried to use Shape and QuadCurve but I couldn't make a perfect semicircle.

Here is a picture of what I'm trying to draw :

enter image description here

like image 410
AwaX Avatar asked Jul 30 '12 09:07

AwaX


2 Answers

The picture you linked is actually a semi-ring. You can get it in JavaFX by drawing nested 2 arcs and some lines. But my preferred way is to use the Path.

public class SemiDemo extends Application {

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();
        root.getChildren().add(drawSemiRing(120, 120, 100, 50, Color.LIGHTGREEN, Color.DARKGREEN));
        root.getChildren().add(drawSemiRing(350, 350, 200, 30, Color.LIGHTSKYBLUE, Color.DARKBLUE));

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Path drawSemiRing(double centerX, double centerY, double radius, double innerRadius, Color bgColor, Color strkColor) {
        Path path = new Path();
        path.setFill(bgColor);
        path.setStroke(strkColor);
        path.setFillRule(FillRule.EVEN_ODD);

        MoveTo moveTo = new MoveTo();
        moveTo.setX(centerX + innerRadius);
        moveTo.setY(centerY);

        ArcTo arcToInner = new ArcTo();
        arcToInner.setX(centerX - innerRadius);
        arcToInner.setY(centerY);
        arcToInner.setRadiusX(innerRadius);
        arcToInner.setRadiusY(innerRadius);

        MoveTo moveTo2 = new MoveTo();
        moveTo2.setX(centerX + innerRadius);
        moveTo2.setY(centerY);

        HLineTo hLineToRightLeg = new HLineTo();
        hLineToRightLeg.setX(centerX + radius);

        ArcTo arcTo = new ArcTo();
        arcTo.setX(centerX - radius);
        arcTo.setY(centerY);
        arcTo.setRadiusX(radius);
        arcTo.setRadiusY(radius);

        HLineTo hLineToLeftLeg = new HLineTo();
        hLineToLeftLeg.setX(centerX - innerRadius);

        path.getElements().add(moveTo);
        path.getElements().add(arcToInner);
        path.getElements().add(moveTo2);
        path.getElements().add(hLineToRightLeg);
        path.getElements().add(arcTo);
        path.getElements().add(hLineToLeftLeg);

        return path;
    }

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

Refer to Shape API of JavaFX for more info about the shapes used in the code.
Screenshot:

enter image description here

like image 135
Uluk Biy Avatar answered Sep 28 '22 08:09

Uluk Biy


Suggestions:

  • If you don't need a full outlining path, you can just use an Arc.
  • If you don't need the arc filled and just want to trace the outline path of the arc, then set the fill of the arc to null.
  • If you want the outline path of the arc thick, then set the stroke parameters on the arc.
  • If you need the a thick arc which is also outlined, then it is best to define a full arc as in Uluk's answer.

Sample code:

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

public class SemiCircleSample extends Application {
  @Override public void start(Stage stage) {
    Arc arc = new Arc(50, 50, 25, 25, 0, 180);
    arc.setType(ArcType.OPEN);
    arc.setStrokeWidth(10);
    arc.setStroke(Color.CORAL);
    arc.setStrokeType(StrokeType.INSIDE);
    arc.setFill(null);

    stage.setScene(new Scene(new Group(arc), 100, 80));
    stage.show();
  }

  public static void main(String[] args) { launch(args); }
}
like image 21
jewelsea Avatar answered Sep 28 '22 08:09

jewelsea