Javafx ArcNode to ("DonutNode")
Scrolling through the javafx documentation stumbled upon the Arc class,I had an idea of building a DonutNode with a label at the center that show percentage.I tried this with a line well,didn't turn out as i wanted cause calculating the angular extent was the problem.
The Arc class to the rescue it has a method that is setLength() which define the angular extent of the arc,what i had to do is just convert from degrees to percentage.
The Node
This class DonutNode extends Region
Arc arc = new Arc();
arc.setCenterX(40.0f);
arc.setCenterY(40.0f);
arc.setRadiusX(35.0f);
arc.setRadiusY(35.0f);
arc.setStartAngle(0.0f);
arc.setStroke(arc_stroke);
arc.setFill(Color.TRANSPARENT);
arc.setStrokeWidth(5);
arc.setType(ArcType.OPEN);
Label label =new Label();
label.setText("0");
label.setFont(Font.font(16));
label.setLayoutX(CENTER-12);
label.setLayoutY(CENTER-16);
label.setContentDisplay(ContentDisplay.CENTER);
label.setTextFill(label_fill);
label.setLabelFor(arc);
Circle c=new Circle();
c.setRadius(30);
c.setFill(circle_fill);
c.setLayoutX(arc.getCenterX());
c.setLayoutY(arc.getCenterY());
this.setStyle("-fx-background-color:black;");
this.setPrefSize(80,80);
this.getChildren().addAll(arc,c,label);//adding children to the Region
The Conversion
public void setPercentage(double percent){
double angle=(18*percent)/5;//from percentage to degrees
arc.setLength(angle);
label.setText(String.valueOf(percent));
}
The Animation
The animation moves the stroke from angle/percent 0 to the setPercentage value,or if in enum Motion.REVERSE from setPercentage to 0.
private void playForwardAnimation(Duration duration){
final Animation animation = new Transition() {
double i=0;
double lenght=getLength();
{
setCycleDuration(duration);
}
@Override
protected void interpolate(double frac) {
if(i==lenght+1){
stop();
}else{
arc.setLength(i);
label.setText(String.valueOf((5*i)/18).split("\\.")[0]);//display percentage
i++;
}
}
};
animation.setRate(0.5);
animation.play();
}
Some DonutNode examples
//i did this just to style the node differently
DonutNode arc=new DonutNode(Color.PINK,Color.YELLOW,Color.TRANSPARENT);
arc.setPercentage(75);
arc.playAnimation(Duration.seconds(5),Motion.FORWARD);
DonutNode arc2=new DonutNode(Color.CYAN,Color.BLUE,Color.TRANSPARENT);
arc2.setPercentage(45);
arc2.playAnimation(Duration.seconds(9),Motion.FORWARD);
DonutNode arc3=new DonutNode(Color.GRAY,Color.MAROON,Color.TAN);
arc3.setPercentage(50);
arc3.playAnimation(Duration.seconds(19),Motion.FORWARD);
DonutNode arc4=new DonutNode(Color.YELLOW,Color.TOMATO,Color.TRANSPARENT);
arc4.setPercentage(90);
arc4.playAnimation(Duration.seconds(29),Motion.FORWARD);
The DonutNode class here
The Results
The Arc class to the rescue it has a method that is setLength() which define the angular extent of the arc,what i had to do is just convert from degrees to percentage.
The Node
This class DonutNode extends Region
Arc arc = new Arc();
arc.setCenterX(40.0f);
arc.setCenterY(40.0f);
arc.setRadiusX(35.0f);
arc.setRadiusY(35.0f);
arc.setStartAngle(0.0f);
arc.setStroke(arc_stroke);
arc.setFill(Color.TRANSPARENT);
arc.setStrokeWidth(5);
arc.setType(ArcType.OPEN);
Label label =new Label();
label.setText("0");
label.setFont(Font.font(16));
label.setLayoutX(CENTER-12);
label.setLayoutY(CENTER-16);
label.setContentDisplay(ContentDisplay.CENTER);
label.setTextFill(label_fill);
label.setLabelFor(arc);
Circle c=new Circle();
c.setRadius(30);
c.setFill(circle_fill);
c.setLayoutX(arc.getCenterX());
c.setLayoutY(arc.getCenterY());
this.setStyle("-fx-background-color:black;");
this.setPrefSize(80,80);
this.getChildren().addAll(arc,c,label);//adding children to the Region
The Conversion
public void setPercentage(double percent){
double angle=(18*percent)/5;//from percentage to degrees
arc.setLength(angle);
label.setText(String.valueOf(percent));
}
The Animation
The animation moves the stroke from angle/percent 0 to the setPercentage value,or if in enum Motion.REVERSE from setPercentage to 0.
private void playForwardAnimation(Duration duration){
final Animation animation = new Transition() {
double i=0;
double lenght=getLength();
{
setCycleDuration(duration);
}
@Override
protected void interpolate(double frac) {
if(i==lenght+1){
stop();
}else{
arc.setLength(i);
label.setText(String.valueOf((5*i)/18).split("\\.")[0]);//display percentage
i++;
}
}
};
animation.setRate(0.5);
animation.play();
}
Some DonutNode examples
//i did this just to style the node differently
DonutNode arc=new DonutNode(Color.PINK,Color.YELLOW,Color.TRANSPARENT);
arc.setPercentage(75);
arc.playAnimation(Duration.seconds(5),Motion.FORWARD);
DonutNode arc2=new DonutNode(Color.CYAN,Color.BLUE,Color.TRANSPARENT);
arc2.setPercentage(45);
arc2.playAnimation(Duration.seconds(9),Motion.FORWARD);
DonutNode arc3=new DonutNode(Color.GRAY,Color.MAROON,Color.TAN);
arc3.setPercentage(50);
arc3.playAnimation(Duration.seconds(19),Motion.FORWARD);
DonutNode arc4=new DonutNode(Color.YELLOW,Color.TOMATO,Color.TRANSPARENT);
arc4.setPercentage(90);
arc4.playAnimation(Duration.seconds(29),Motion.FORWARD);
The DonutNode class here
The Results
Comments
Post a Comment