下面列出了怎么用javafx.scene.shape.StrokeLineJoin的API类实例代码及写法,或者点击链接到github查看源代码。
/** @param color Color to display */
public void setColor(final WidgetColor color)
{
final GraphicsContext gc = blob.getGraphicsContext2D();
gc.setFill(JFXUtil.convert(color));
gc.fillRect(0, 0, 16, 16);
gc.setLineCap(StrokeLineCap.SQUARE);
gc.setLineJoin(StrokeLineJoin.MITER);
gc.setLineWidth(1.75);
gc.setStroke(Color.BLACK);
gc.strokeRect(0, 0, 16, 16);
button.setText(String.valueOf(color));
}
private static void setStroke(Shape shape, Double penwidth, String color,
String fillColor) {
if (shape != null) {
String style = ""; //$NON-NLS-1$
if (color == null) {
color = "#000000"; // the default color is black //$NON-NLS-1$
}
style += "-fx-stroke: " + color + ";"; //$NON-NLS-1$ //$NON-NLS-2$
if (fillColor == null) {
fillColor = color;
}
style += "-fx-fill: " + fillColor + ";"; //$NON-NLS-1$ //$NON-NLS-2$
if (penwidth != null) {
style += "-fx-stroke-width: " + penwidth + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
shape.setStyle(style);
shape.setStrokeLineJoin(StrokeLineJoin.ROUND);
}
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
@Override
public Group createJFXNode() throws Exception
{
final Polyline polyline = new Polyline();
polyline.setStrokeLineJoin(StrokeLineJoin.MITER);
polyline.setStrokeLineCap(StrokeLineCap.BUTT);
return new Group(polyline, new Arrow(), new Arrow());
}
@Override
public Polygon createJFXNode() throws Exception
{
final Polygon polygon = new Polygon();
polygon.setStrokeLineJoin(StrokeLineJoin.ROUND);
polygon.setStrokeLineCap(StrokeLineCap.BUTT);
return polygon;
}
@Override
public void start(final Stage stage) throws Exception
{
poly.setStroke(Color.BLUE);
poly.setStrokeWidth(4);
poly.setStrokeLineCap(StrokeLineCap.ROUND);
poly.setStrokeLineJoin(StrokeLineJoin.ROUND);
poly.setFill(Color.CORNSILK);
final Group root = new Group();
root.getChildren().add(poly);
final Scene scene = new Scene(root, 400, 400);
stage.setScene(scene);
stage.show();
EditorUtil.setSceneStyle(scene);
editor = new PointsEditor(root, (x, y) -> new Point2D(x, y), points, new PointsEditorListener()
{
@Override
public void pointsChanged(final Points points)
{
updatePoly();
}
@Override
public void done()
{
editor.dispose();
}
});
updatePoly();
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
@Override
protected GeometryNode<IGeometry> doCreateVisual() {
GeometryNode<IGeometry> visual = super.doCreateVisual();
visual.setStroke(Color.GREY);
visual.getStrokeDashArray().add(5.0);
visual.setStrokeLineJoin(StrokeLineJoin.BEVEL);
visual.setStrokeType(StrokeType.CENTERED);
return visual;
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
@Override
public ObjectProperty<StrokeLineJoin> strokeLineJoinProperty() {
if (strokeLineJoin == null) {
strokeLineJoin = new SimpleObjectProperty<>(this, "strokeLineJoin", DEFAULT_STROKE_LINE_JOIN);
strokeLineJoin.addListener((v, o, n) -> forwardShapeProperty(s -> setStrokeLineJoin(n)));
}
return strokeLineJoin;
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
@Override
public void drawLine(double x, double y, double x1, double y1)
{
ctx.setLineCap(StrokeLineCap.ROUND);
ctx.setLineJoin(StrokeLineJoin.MITER);
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x1,y1);
ctx.stroke();
}
private void createHatchingLine(final Group group, final double x1, final double y1, final double x2, final double y2,
final double clipWidth, final double clipHeight) {
final javafx.scene.shape.Line line = new javafx.scene.shape.Line();
line.setStrokeWidth(model.getHatchingsWidth());
line.setStrokeLineJoin(StrokeLineJoin.MITER);
line.setStrokeLineCap(StrokeLineCap.SQUARE);
line.setStroke(model.getHatchingsCol().toJFX());
line.setStartX(x1);
line.setStartY(y1);
line.setEndX(x2);
line.setEndY(y2);
// Required, otherwise the line may not be drawn.
line.setClip(new Rectangle(0, 0, clipWidth, clipHeight));
group.getChildren().add(line);
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
/**
* Maps a line join code from AWT to the corresponding JavaFX
* StrokeLineJoin enum value.
*
* @param c the line join code.
*
* @return A JavaFX line join value.
*/
private StrokeLineJoin awtToJavaFXLineJoin(int j) {
if (j == BasicStroke.JOIN_BEVEL) {
return StrokeLineJoin.BEVEL;
} else if (j == BasicStroke.JOIN_MITER) {
return StrokeLineJoin.MITER;
} else if (j == BasicStroke.JOIN_ROUND) {
return StrokeLineJoin.ROUND;
} else {
throw new IllegalArgumentException("Unrecognised join code: " + j);
}
}
@Override protected void initGraphics() {
super.initGraphics();
averagingListener = o -> handleEvents("AVERAGING");
timeFormatter = DateTimeFormatter.ofPattern("HH:mm", tile.getLocale());
if (tile.isAutoScale()) tile.calcAutoScale();
niceScaleY = new NiceScale(tile.getMinValue(), tile.getMaxValue());
niceScaleY.setMaxTicks(5);
tickLineColor = Color.color(tile.getChartGridColor().getRed(), tile.getChartGridColor().getGreen(), tile.getChartGridColor().getBlue(), 0.5);
horizontalTickLines = new ArrayList<>(5);
tickLabelsY = new ArrayList<>(5);
for (int i = 0 ; i < 5 ; i++) {
Line hLine = new Line(0, 0, 0, 0);
hLine.getStrokeDashArray().addAll(1.0, 2.0);
hLine.setStroke(Color.TRANSPARENT);
horizontalTickLines.add(hLine);
Text tickLabelY = new Text("");
tickLabelY.setFill(Color.TRANSPARENT);
tickLabelsY.add(tickLabelY);
}
gradientLookup = new GradientLookup(tile.getGradientStops());
low = tile.getMaxValue();
high = tile.getMinValue();
stdDeviation = 0;
movingAverage = tile.getMovingAverage();
noOfDatapoints = tile.getAveragingPeriod();
dataList = new LinkedList<>();
// To get smooth lines in the chart we need at least 4 values
if (noOfDatapoints < 4) throw new IllegalArgumentException("Please increase the averaging period to a value larger than 3.");
graphBounds = new Rectangle(PREFERRED_WIDTH * 0.05, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.9, PREFERRED_HEIGHT * 0.45);
titleText = new Text(tile.getTitle());
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
valueText = new Text(String.format(locale, formatString, tile.getValue()));
valueText.setFill(tile.getValueColor());
Helper.enableNode(valueText, tile.isValueVisible());
unitText = new Text(tile.getUnit());
unitText.setFill(tile.getUnitColor());
Helper.enableNode(unitText, !tile.getUnit().isEmpty());
valueUnitFlow = new TextFlow(valueText, unitText);
valueUnitFlow.setTextAlignment(TextAlignment.RIGHT);
averageText = new Text(String.format(locale, formatString, tile.getAverage()));
averageText.setFill(Tile.FOREGROUND);
Helper.enableNode(averageText, tile.isAverageVisible());
highText = new Text();
highText.setTextOrigin(VPos.BOTTOM);
highText.setFill(tile.getValueColor());
lowText = new Text();
lowText.setTextOrigin(VPos.TOP);
lowText.setFill(tile.getValueColor());
text = new Text(tile.getText());
text.setTextOrigin(VPos.TOP);
text.setFill(tile.getTextColor());
timeSpanText = new Text("");
timeSpanText.setTextOrigin(VPos.TOP);
timeSpanText.setFill(tile.getTextColor());
Helper.enableNode(timeSpanText, !tile.isTextVisible());
stdDeviationArea = new Rectangle();
Helper.enableNode(stdDeviationArea, tile.isAverageVisible());
averageLine = new Line();
averageLine.setStroke(Tile.FOREGROUND);
averageLine.getStrokeDashArray().addAll(PREFERRED_WIDTH * 0.005, PREFERRED_WIDTH * 0.005);
Helper.enableNode(averageLine, tile.isAverageVisible());
pathElements = new ArrayList<>(noOfDatapoints);
pathElements.add(0, new MoveTo());
for (int i = 1 ; i < noOfDatapoints ; i++) { pathElements.add(i, new LineTo()); }
sparkLine = new Path();
sparkLine.getElements().addAll(pathElements);
sparkLine.setFill(null);
sparkLine.setStroke(tile.getBarColor());
sparkLine.setStrokeWidth(PREFERRED_WIDTH * 0.0075);
sparkLine.setStrokeLineCap(StrokeLineCap.ROUND);
sparkLine.setStrokeLineJoin(StrokeLineJoin.ROUND);
dot = new Circle();
dot.setFill(tile.getBarColor());
getPane().getChildren().addAll(titleText, valueUnitFlow, stdDeviationArea, averageLine, sparkLine, dot, averageText, highText, lowText, timeSpanText, text);
getPane().getChildren().addAll(horizontalTickLines);
getPane().getChildren().addAll(tickLabelsY);
}
@Override protected void initGraphics() {
super.initGraphics();
averagingListener = o -> handleEvents("AVERAGING_PERIOD");
timeFormatter = DateTimeFormatter.ofPattern("HH:mm", tile.getLocale());
state = State.CONSTANT;
if (tile.isAutoScale()) tile.calcAutoScale();
low = tile.getMaxValue();
high = tile.getMinValue();
movingAverage = tile.getMovingAverage();
noOfDatapoints = tile.getAveragingPeriod();
dataList = new LinkedList<>();
// To get smooth lines in the chart we need at least 4 values
if (noOfDatapoints < 4) throw new IllegalArgumentException("Please increase the averaging period to a value larger than 3.");
graphBounds = new Rectangle(PREFERRED_WIDTH * 0.05, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.9, PREFERRED_HEIGHT * 0.45);
titleText = new Text(tile.getTitle());
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
valueText = new Text(String.format(locale, formatString, tile.getValue()));
valueText.setBoundsType(TextBoundsType.VISUAL);
valueText.setFill(tile.getValueColor());
Helper.enableNode(valueText, tile.isValueVisible());
valueUnitFlow = new TextFlow(valueText);
valueUnitFlow.setTextAlignment(TextAlignment.RIGHT);
highText = new Text();
highText.setTextOrigin(VPos.BOTTOM);
highText.setFill(tile.getValueColor());
lowText = new Text();
lowText.setTextOrigin(VPos.TOP);
lowText.setFill(tile.getValueColor());
text = new Text(tile.getText());
text.setTextOrigin(VPos.TOP);
text.setFill(tile.getTextColor());
timeSpanText = new Text("");
timeSpanText.setTextOrigin(VPos.TOP);
timeSpanText.setFill(tile.getTextColor());
Helper.enableNode(timeSpanText, !tile.isTextVisible());
referenceLine = new Line();
referenceLine.getStrokeDashArray().addAll(3d, 3d);
referenceLine.setVisible(false);
pathElements = new ArrayList<>(noOfDatapoints);
pathElements.add(0, new MoveTo());
for (int i = 1 ; i < noOfDatapoints ; i++) { pathElements.add(i, new LineTo()); }
sparkLine = new Path();
sparkLine.getElements().addAll(pathElements);
sparkLine.setFill(null);
sparkLine.setStroke(tile.getBarColor());
sparkLine.setStrokeWidth(PREFERRED_WIDTH * 0.0075);
sparkLine.setStrokeLineCap(StrokeLineCap.ROUND);
sparkLine.setStrokeLineJoin(StrokeLineJoin.ROUND);
dot = new Circle();
dot.setFill(tile.getBarColor());
dot.setVisible(false);
triangle = new Path();
triangle.setStroke(null);
triangle.setFill(state.color);
indicatorPane = new StackPane(triangle);
changeText = new Label(String.format(locale, "%." + tile.getTickLabelDecimals() + "f", (tile.getCurrentValue() - tile.getReferenceValue())));
changeText.setTextFill(state.color);
changeText.setAlignment(Pos.CENTER_RIGHT);
changePercentageText = new Text(new StringBuilder().append(String.format(locale, "%." + tile.getTickLabelDecimals() + "f", (tile.getCurrentValue() / tile.getReferenceValue() * 100.0) - 100.0)).append("\u0025").toString());
changePercentageText.setFill(state.color);
changePercentageFlow = new TextFlow(indicatorPane, changePercentageText);
changePercentageFlow.setTextAlignment(TextAlignment.RIGHT);
getPane().getChildren().addAll(titleText, valueUnitFlow, sparkLine, dot, referenceLine, highText, lowText, timeSpanText, text, changeText, changePercentageFlow);
}
@Override protected void initGraphics() {
super.initGraphics();
averagingListener = o -> handleEvents("AVERAGING_PERIOD");
timeFormatter = DateTimeFormatter.ofPattern("HH:mm", tile.getLocale());
state = State.CONSTANT;
if (tile.isAutoScale()) tile.calcAutoScale();
low = tile.getMaxValue();
high = tile.getMinValue();
movingAverage = tile.getMovingAverage();
noOfDatapoints = tile.getAveragingPeriod();
dataList = new LinkedList<>();
// To get smooth lines in the chart we need at least 4 values
if (noOfDatapoints < 4) throw new IllegalArgumentException("Please increase the averaging period to a value larger than 3.");
graphBounds = new Rectangle(PREFERRED_WIDTH * 0.05, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.9, PREFERRED_HEIGHT * 0.45);
titleText = new Text(tile.getTitle());
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
valueText = new Text(String.format(locale, formatString, tile.getValue()));
valueText.setBoundsType(TextBoundsType.VISUAL);
valueText.setFill(tile.getValueColor());
Helper.enableNode(valueText, tile.isValueVisible());
valueUnitFlow = new TextFlow(valueText);
valueUnitFlow.setTextAlignment(TextAlignment.RIGHT);
highText = new Text();
highText.setTextOrigin(VPos.BOTTOM);
highText.setFill(tile.getValueColor());
lowText = new Text();
lowText.setTextOrigin(VPos.TOP);
lowText.setFill(tile.getValueColor());
text = new Text(tile.getText());
text.setTextOrigin(VPos.TOP);
text.setFill(tile.getTextColor());
timeSpanText = new Text("");
timeSpanText.setTextOrigin(VPos.TOP);
timeSpanText.setFill(tile.getTextColor());
Helper.enableNode(timeSpanText, !tile.isTextVisible());
referenceLine = new Line();
referenceLine.getStrokeDashArray().addAll(3d, 3d);
referenceLine.setVisible(false);
pathElements = new ArrayList<>(noOfDatapoints);
pathElements.add(0, new MoveTo());
for (int i = 1 ; i < noOfDatapoints ; i++) { pathElements.add(i, new LineTo()); }
sparkLine = new Path();
sparkLine.getElements().addAll(pathElements);
sparkLine.setFill(null);
sparkLine.setStroke(tile.getBarColor());
sparkLine.setStrokeWidth(PREFERRED_WIDTH * 0.0075);
sparkLine.setStrokeLineCap(StrokeLineCap.ROUND);
sparkLine.setStrokeLineJoin(StrokeLineJoin.ROUND);
dot = new Circle();
dot.setFill(tile.getBarColor());
dot.setVisible(false);
triangle = new Path();
triangle.setStroke(null);
triangle.setFill(state.color);
indicatorPane = new StackPane(triangle);
changeText = new Label(String.format(locale, "%." + tile.getTickLabelDecimals() + "f", (tile.getCurrentValue() - tile.getReferenceValue())));
changeText.setTextFill(state.color);
changeText.setAlignment(Pos.CENTER_RIGHT);
changePercentageText = new Text(new StringBuilder().append(String.format(locale, "%." + tile.getTickLabelDecimals() + "f", (tile.getCurrentValue() / tile.getReferenceValue() * 100.0) - 100.0)).append(Helper.PERCENTAGE).toString());
changePercentageText.setFill(state.color);
changePercentageFlow = new TextFlow(indicatorPane, changePercentageText);
changePercentageFlow.setTextAlignment(TextAlignment.RIGHT);
getPane().getChildren().addAll(titleText, valueUnitFlow, sparkLine, dot, referenceLine, highText, lowText, timeSpanText, text, changeText, changePercentageFlow);
}
private void initGraphics() {
// Set initial size
if (Double.compare(gauge.getPrefWidth(), 0.0) <= 0 || Double.compare(gauge.getPrefHeight(), 0.0) <= 0 ||
Double.compare(gauge.getWidth(), 0.0) <= 0 || Double.compare(gauge.getHeight(), 0.0) <= 0) {
if (gauge.getPrefWidth() > 0 && gauge.getPrefHeight() > 0) {
gauge.setPrefSize(gauge.getPrefWidth(), gauge.getPrefHeight());
} else {
gauge.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
}
graphBounds = new Rectangle(PREFERRED_WIDTH * 0.05, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.9, PREFERRED_HEIGHT * 0.45);
titleText = new Text(gauge.getTitle());
titleText.setFill(gauge.getTitleColor());
Helper.enableNode(titleText, !gauge.getTitle().isEmpty());
valueText = new Text(String.format(locale, formatString, gauge.getValue()));
valueText.setFill(gauge.getValueColor());
Helper.enableNode(valueText, gauge.isValueVisible());
unitText = new Text(gauge.getUnit());
unitText.setFill(gauge.getUnitColor());
Helper.enableNode(unitText, !gauge.getUnit().isEmpty());
averageText = new Text(String.format(locale, formatString, gauge.getAverage()));
averageText.setFill(gauge.getAverageColor());
Helper.enableNode(averageText, gauge.isAverageVisible());
highText = new Text();
highText.setTextOrigin(VPos.BOTTOM);
highText.setFill(gauge.getValueColor());
lowText = new Text();
lowText.setTextOrigin(VPos.TOP);
lowText.setFill(gauge.getValueColor());
subTitleText = new Text(gauge.getSubTitle());
subTitleText.setTextOrigin(VPos.TOP);
subTitleText.setFill(gauge.getSubTitleColor());
stdDeviationArea = new Rectangle();
Helper.enableNode(stdDeviationArea, gauge.isAverageVisible());
averageLine = new Line();
averageLine.setStroke(gauge.getAverageColor());
averageLine.getStrokeDashArray().addAll(PREFERRED_WIDTH * 0.005, PREFERRED_WIDTH * 0.005);
Helper.enableNode(averageLine, gauge.isAverageVisible());
pathElements = new ArrayList<>(noOfDatapoints);
pathElements.add(0, new MoveTo());
for (int i = 1 ; i < noOfDatapoints ; i++) { pathElements.add(i, new LineTo()); }
sparkLine = new Path();
sparkLine.getElements().addAll(pathElements);
sparkLine.setFill(null);
sparkLine.setStroke(gauge.getBarColor());
sparkLine.setStrokeWidth(PREFERRED_WIDTH * 0.0075);
sparkLine.setStrokeLineCap(StrokeLineCap.ROUND);
sparkLine.setStrokeLineJoin(StrokeLineJoin.ROUND);
dot = new Circle();
dot.setFill(gauge.getBarColor());
pane = new Pane(titleText, valueText, unitText, stdDeviationArea, averageLine, sparkLine, dot, averageText, highText, lowText, subTitleText);
pane.setBorder(new Border(new BorderStroke(gauge.getBorderPaint(), BorderStrokeStyle.SOLID, new CornerRadii(PREFERRED_WIDTH * 0.025), new BorderWidths(gauge.getBorderWidth()))));
pane.setBackground(new Background(new BackgroundFill(gauge.getBackgroundPaint(), new CornerRadii(PREFERRED_WIDTH * 0.025), Insets.EMPTY)));
getChildren().setAll(pane);
}
private void initGraphics() {
// Set initial size
if (Double.compare(gauge.getPrefWidth(), 0.0) <= 0 || Double.compare(gauge.getPrefHeight(), 0.0) <= 0 ||
Double.compare(gauge.getWidth(), 0.0) <= 0 || Double.compare(gauge.getHeight(), 0.0) <= 0) {
if (gauge.getPrefWidth() > 0 && gauge.getPrefHeight() > 0) {
gauge.setPrefSize(gauge.getPrefWidth(), gauge.getPrefHeight());
} else {
gauge.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
}
sectionsCanvas = new Canvas(PREFERRED_WIDTH, PREFERRED_HEIGHT);
sectionsCtx = sectionsCanvas.getGraphicsContext2D();
needleRotate = new Rotate(180 - START_ANGLE);
angleStep = ANGLE_RANGE / (gauge.getRange());
double targetAngle = 180 - START_ANGLE + (gauge.getValue() - gauge.getMinValue()) * angleStep;
needleRotate.setAngle(Helper.clamp(180 - START_ANGLE, 180 - START_ANGLE + ANGLE_RANGE, targetAngle));
needleMoveTo1 = new MoveTo();
needleCubicCurveTo2 = new CubicCurveTo();
needleCubicCurveTo3 = new CubicCurveTo();
needleCubicCurveTo4 = new CubicCurveTo();
needleLineTo5 = new LineTo();
needleLineTo6 = new LineTo();
needleCubicCurveTo7 = new CubicCurveTo();
needleClosePath8 = new ClosePath();
needle = new Path(needleMoveTo1, needleCubicCurveTo2, needleCubicCurveTo3, needleCubicCurveTo4, needleLineTo5, needleLineTo6, needleCubicCurveTo7, needleClosePath8);
needle.setFillRule(FillRule.EVEN_ODD);
needle.getTransforms().setAll(needleRotate);
needle.setFill(gauge.getNeedleColor());
needle.setStroke(gauge.getBorderPaint());
needle.setStrokeLineCap(StrokeLineCap.ROUND);
needle.setStrokeLineJoin(StrokeLineJoin.BEVEL);
valueText = new Text(formatNumber(gauge.getLocale(), gauge.getFormatString(), gauge.getDecimals(), gauge.getMinValue()) + gauge.getUnit());
valueText.setMouseTransparent(true);
valueText.setTextOrigin(VPos.CENTER);
valueText.setFill(gauge.getValueColor());
enableNode(valueText, gauge.isValueVisible());
titleText = new Text(gauge.getTitle());
titleText.setTextOrigin(VPos.CENTER);
titleText.setFill(gauge.getTitleColor());
enableNode(titleText, !gauge.getTitle().isEmpty());
subTitleText = new Text(gauge.getSubTitle());
subTitleText.setTextOrigin(VPos.CENTER);
subTitleText.setFill(gauge.getSubTitleColor());
enableNode(subTitleText, !gauge.getSubTitle().isEmpty());
// Add all nodes
pane = new Pane(sectionsCanvas, needle, valueText, titleText, subTitleText);
getChildren().setAll(pane);
}
public ArrowHead() {
super(0, 0, 10, 3, 10, -3);
setFill(Color.WHITE);
setStroke(Color.BLACK);
setStrokeLineJoin(StrokeLineJoin.ROUND);
}
default StrokeLineJoin getStrokeLineJoin() {
return strokeLineJoinProperty().get();
}
default void setStrokeLineJoin(StrokeLineJoin strokeLineJoin) {
strokeLineJoinProperty().set(strokeLineJoin);
}
public StarIcon(double size, Color fill)
{
super(size);
double rm = size * 0.4;
double r0 = size * 0.15;
double w = size * 0.0325;
FxPath p = new FxPath();
p.setStrokeLineCap(StrokeLineCap.ROUND);
p.setStrokeLineJoin(StrokeLineJoin.ROUND);
p.setStroke(Color.BLACK);
p.setStrokeWidth(w);
p.setFill(fill);
for(int i=0; i<11; i++)
{
double a = Math.PI * i / 5;
double r = CKit.isEven(i) ? rm : r0;
double x = r * Math.cos(a);
double y = r * Math.sin(a);
switch(i)
{
case 0:
p.moveto(x, y);
break;
case 10:
p.close();
break;
default:
p.lineto(x, y);
break;
}
}
Group g = new Group(p);
g.setRotate(-90);
g.setTranslateX(size * 0.5);
g.setTranslateY(size * 0.5);
add(g);
}
public void setStrokeLineJoin(StrokeLineJoin x)
{
lineJoin = x;
}
private void drawForeground() {
ctxFg.clearRect(0, 0, width, height);
ctxFg.setStroke(getSkinnable().getSeriesStroke());
ctxFg.setLineCap(StrokeLineCap.ROUND);
ctxFg.setLineJoin(StrokeLineJoin.ROUND);
ctxFg.setLineWidth(0.025 * height);
ctxFg.save();
ctxFg.translate(0, sectionMinimum * heightFactor);
widthFactor = width / (getSkinnable().getSeries().getData().size());
int noOfDataPoints = getSkinnable().getSeries().getData().size();
if (noOfDataPoints > 2) {
for (int i = 0 ; i < noOfDataPoints - 1 ; i++) {
XYChart.Data p1 = (XYChart.Data) getSkinnable().getSeries().getData().get(i);
XYChart.Data p2 = (XYChart.Data) getSkinnable().getSeries().getData().get(i + 1);
ctxFg.strokeLine(widthFactor / 2 + i * widthFactor, height - (Double) p1.getYValue() * heightFactor, widthFactor / 2 + (i + 1) * widthFactor, height - (Double) p2.getYValue() * heightFactor);
drawBullet(ctxFg, widthFactor / 2 + i * widthFactor, height - (Double) p1.getYValue() * heightFactor, getSkinnable().getBulletFill());
}
drawBullet(ctxFg, widthFactor / 2 + (noOfDataPoints - 1) * widthFactor, height - (Double) (getSkinnable().getSeries().getData().get(noOfDataPoints - 1)).getYValue() * heightFactor, getSkinnable().getBulletFill());
}
ctxFg.save();
ctxFg.applyEffect(new DropShadow(0.025 * height, 0, 0.025 * height, Color.rgb(0, 0, 0, 0.65)));
ctxFg.restore();
// draw from and to text
ctxFg.setFill(Color.WHITE);
ctxFg.setFont(Font.font("Open Sans", height * 0.1));
ctxFg.setTextBaseline(VPos.BOTTOM);
ctxFg.setTextAlign(TextAlignment.LEFT);
ctxFg.fillText(getSkinnable().getFrom(), 2, height - 2);
ctxFg.setTextAlign(TextAlignment.RIGHT);
ctxFg.fillText(getSkinnable().getTo(), width - 2, height -2);
// draw title text
if (getSkinnable().isTitleVisible()) {
ctxFg.setTextBaseline(VPos.TOP);
ctxFg.setTextAlign(TextAlignment.CENTER);
ctxFg.fillText(getSkinnable().getSeries().getName(), width * 0.5, 2);
}
ctxFg.restore();
}
/**
* Creates the view.
* @param sh The model.
*/
ViewSingleShape(final S sh) {
super(sh);
border = createJFXShape();
border.setStrokeLineJoin(StrokeLineJoin.MITER);
border.setStrokeLineCap(StrokeLineCap.BUTT);
if(model.isShadowable()) {
shadow = createJFXShape();
shadow.setStrokeLineCap(StrokeLineCap.BUTT);
getChildren().add(shadow);
shadowSetCall = (obs, oldVal, newVal) -> {
shadow.setDisable(!newVal);
if(newVal && model.isFillable() && model.shadowFillsShape()) {
border.setFill(getFillingPaint(model.getFillingStyle()));
}
};
model.shadowProperty().addListener(shadowSetCall);
shadow.strokeProperty().bind(Bindings.createObjectBinding(() -> model.getShadowCol().toJFX(), model.shadowColProperty()));
shadow.fillProperty().bind(Bindings.createObjectBinding(
() -> model.isFillable() && (model.isFilled() || model.shadowFillsShape()) ? model.getShadowCol().toJFX() : null, model.shadowColProperty()));
model.shadowAngleProperty().addListener(shadowUpdateCall);
model.shadowSizeProperty().addListener(shadowUpdateCall);
shadow.strokeTypeProperty().bind(border.strokeTypeProperty());
shadow.visibleProperty().bind(Bindings.createBooleanBinding(() -> !shadow.isDisable(), shadow.disableProperty()));
shadow.setDisable(!model.hasShadow());
}else {
shadow = null;
shadowSetCall = null;
}
getChildren().add(border);
if(model.isDbleBorderable()) {
dblBorder = createJFXShape();
getChildren().add(dblBorder);
dblBorder.setFill(null);
dblBorder.setStrokeLineCap(StrokeLineCap.BUTT);
dblBorder.layoutXProperty().bind(border.layoutXProperty());
dblBorder.layoutYProperty().bind(border.layoutYProperty());
model.dbleBordProperty().addListener((ChangeListener<? super Boolean>) strokesUpdateCall);
model.dbleBordSepProperty().addListener((ChangeListener<? super Number>) strokesUpdateCall);
model.dbleBordColProperty().addListener((ChangeListener<? super Color>) strokesUpdateCall);
dblBorder.visibleProperty().bind(Bindings.createBooleanBinding(() -> !dblBorder.isDisable(), dblBorder.disableProperty()));
} else {
dblBorder = null;
}
if(model.isFillable()) {
fillUpdateCall = (obs, oldVal, newVal) -> border.setFill(getFillingPaint(model.getFillingStyle()));
model.fillingProperty().addListener((ChangeListener<? super FillingStyle>) fillUpdateCall);
model.gradColStartProperty().addListener((ChangeListener<? super Color>) fillUpdateCall);
model.gradColEndProperty().addListener((ChangeListener<? super Color>) fillUpdateCall);
model.gradMidPtProperty().addListener((ChangeListener<? super Number>) fillUpdateCall);
model.gradAngleProperty().addListener((ChangeListener<? super Number>) fillUpdateCall);
model.fillingColProperty().addListener((ChangeListener<? super Color>) fillUpdateCall);
model.hatchingsAngleProperty().addListener((ChangeListener<? super Number>) fillUpdateCall);
model.hatchingsSepProperty().addListener((ChangeListener<? super Number>) fillUpdateCall);
model.hatchingsWidthProperty().addListener((ChangeListener<? super Number>) fillUpdateCall);
model.hatchingsColProperty().addListener((ChangeListener<? super Color>) fillUpdateCall);
border.setFill(getFillingPaint(model.getFillingStyle()));
// The filling must be updated on resize and co.
border.boundsInLocalProperty().addListener((ChangeListener<? super Bounds>) fillUpdateCall);
}else {
fillUpdateCall = null;
}
border.strokeProperty().bind(Bindings.createObjectBinding(() -> model.getLineColour().toJFX(), model.lineColourProperty()));
setUpLine();
bindBorderMovable();
updateStrokes();
updateShadowPosition();
bindRotationAngle();
}
/**
* Retrieves the value of the stroke line join property.
*
* @return The value of the stroke line join property.
*
* @see javafx.scene.shape.Shape#getStrokeLineJoin()
*/
public final StrokeLineJoin getStrokeLineJoin() {
return geometricShape.getStrokeLineJoin();
}
/**
* Sets the value of the stroke line join property.
*
* @param value
* The new value of the stroke line join property.
*
* @see javafx.scene.shape.Shape#setStrokeLineJoin(javafx.scene.shape.StrokeLineJoin)
*/
public final void setStrokeLineJoin(StrokeLineJoin value) {
geometricShape.setStrokeLineJoin(value);
}
/**
* Provides a {@link Property} holding the stroke line join to apply for
* this {@link GeometryNode}.
*
* @return A (writable) property for the stroke line join of this node.
*
* @see javafx.scene.shape.Shape#strokeLineJoinProperty()
*/
public final ObjectProperty<StrokeLineJoin> strokeLineJoinProperty() {
return geometricShape.strokeLineJoinProperty();
}