import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.TimelineBuilder;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcBuilder;
import javafx.scene.shape.ArcType;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.RotateBuilder;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FxGauge extends Application {
private DoubleProperty rotateAngle = new SimpleDoubleProperty();
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Fx Gauge");
Pane root = new Pane();
Scene scene = new Scene(root, 500, 500);
scene.getStylesheets().add(
FxGauge.class.getResource("gauge.css").toExternalForm());
Group gauge = drawGauge();
Group ribbon = drawRibbon();
Group center = drawArrow();
Group texts = drawTexts();
root.getChildren().addAll(gauge, ribbon, center, texts);
primaryStage.setScene(scene);
primaryStage.show();
}
private Group drawGauge() {
Group gauge = new Group();
Circle circle = new Circle(250, 250, 200);
Rectangle rectangle = new Rectangle(50, 360, 400, 100);
Shape radial = Shape.subtract(circle, rectangle);
radial.getStyleClass().add("radial");
Rectangle bottom = new Rectangle(80, 372, 340, 60);
bottom.setArcWidth(12);
bottom.setArcHeight(12);
bottom.getStyleClass().add("bottom");
gauge.getChildren().addAll(bottom, radial);
return gauge;
}
private Group drawRibbon() {
Group ribbon = new Group();
for (int i = 0; i < 5; i++) {
Arc outerArc = ArcBuilder.create().centerX(250).centerY(250)
.radiusX(180).radiusY(180).startAngle(0).length(46)
.type(ArcType.ROUND).fill(Color.CORAL).build();
Arc innerArc = ArcBuilder.create().centerX(250).centerY(250)
.radiusX(160).radiusY(160).startAngle(0).length(46)
.type(ArcType.ROUND).fill(Color.CORAL).build();
Shape arc = Shape.subtract(outerArc, innerArc);
arc.getStyleClass().add("ribbon-" + i);
arc.getTransforms().add(
RotateBuilder.create().pivotX(innerArc.getCenterX())
.pivotY(innerArc.getCenterY()).pivotZ(0)
.axis(Rotate.Z_AXIS).angle(-165 + 49 * i).build());
ribbon.getChildren().add(arc);
}
return ribbon;
}
private Group drawArrow() {
Group arrowDial = new Group();
Circle circle = new Circle(250, 250, 28);
circle.getStyleClass().add("center");
Line arrow = new Line(250, 250, 360, 250);
arrow.setStrokeWidth(8);
arrow.setStrokeType(StrokeType.CENTERED);
arrow.getStyleClass().add("arrow");
arrowDial.getChildren().addAll(arrow, circle);
Rotate rotate = RotateBuilder.create().pivotX(250).pivotY(250)
.pivotZ(0).axis(Rotate.Z_AXIS).build();
arrowDial.getTransforms().add(rotate);
rotate.angleProperty().bind(rotateAngle);
TimelineBuilder
.create()
.keyFrames(
new KeyFrame(Duration.seconds(0), new KeyValue(
rotateAngle, -214)),
new KeyFrame(Duration.seconds(6), new KeyValue(
rotateAngle, 32)))
.cycleCount(Timeline.INDEFINITE).autoReverse(true).build()
.play();
return arrowDial;
}
private Group drawTexts() {
Group textValues = new Group();
for (int i = 0; i <= 5; i++) {
Text text = new Text(i * 2 + "0");
text.setX(130);
text.setTranslateX(250);
text.setTranslateY(250);
text.getStyleClass().add("text");
text.getTransforms().add(new Rotate(-162 + 49 * (i - 1)));
textValues.getChildren().addAll(text);
}
return textValues;
}
public static void main(String[] args) {
launch(args);
}
}