All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jfxtras.labs.internal.scene.control.skin.SimpleRadialGaugeSkin Maven / Gradle / Ivy

There is a newer version: 9.0-r1
Show newest version
/*
 * Copyright (c) 2012, JFXtras
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions are met:
 *       * Redistributions of source code must retain the above copyright
 *         notice, this list of conditions and the following disclaimer.
 *       * Redistributions in binary form must reproduce the above copyright
 *         notice, this list of conditions and the following disclaimer in the
 *         documentation and/or other materials provided with the distribution.
 *       * Neither the name of the  nor the
 *         names of its contributors may be used to endorse or promote products
 *         derived from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
 *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package jfxtras.labs.internal.scene.control.skin;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.geometry.VPos;
import javafx.scene.CacheHint;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.InnerShadow;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.util.Duration;
import jfxtras.labs.internal.scene.control.behavior.SimpleRadialGaugeBehavior;
import jfxtras.labs.scene.control.gauge.Section;
import jfxtras.labs.scene.control.gauge.SimpleRadialGauge;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;


/**
 * Created with IntelliJ IDEA.
 * User: hansolo
 * Date: 10.09.12
 * Time: 15:16
 * To change this template use File | Settings | File Templates.
 */
public class SimpleRadialGaugeSkin extends GaugeSkinBase {
    private static final double INSETS = 4;
    private SimpleRadialGauge control;
    private boolean           isDirty;
    private boolean           initialized;
    private Canvas            canvas;
    private GraphicsContext   ctx;
    private Pane              gauge;
    private Point2D           center;
    private Arc               bar;
    private Text              valueText;
    private NumberFormat      valueFormat;
    private Text              unitText;
    private Timeline          timeline;
    private DoubleProperty    gaugeValue;
    private double            size;
    private Text              minLabel;
    private Text              maxLabel;
    private Stop[]            barGradientStops;
    private double            xy;
    private double            wh;
    private double            startAngle;
    private double            length;
    private Canvas            alertIndicator;


    // ******************** Constructors **************************************
    public SimpleRadialGaugeSkin(final SimpleRadialGauge CONTROL) {
        super(CONTROL, new SimpleRadialGaugeBehavior(CONTROL));
        control          = CONTROL;
        initialized      = false;
        isDirty          = false;
        canvas           = new Canvas();
        ctx              = canvas.getGraphicsContext2D();
        gauge            = new Pane();
        center           = new Point2D(100, 100);
        bar              = new Arc();
        valueText        = new Text(Double.toString(control.getValue()));
        valueFormat      = new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.US));
        unitText         = new Text(control.getUnit());
        timeline         = new Timeline();
        gaugeValue       = new SimpleDoubleProperty(control.getValue());
        size             = 200;
        minLabel         = new Text(valueFormat.format(control.getMinValue()));
        maxLabel         = new Text(valueFormat.format(control.getMaxValue()));
        xy               = (control.getBarWidth() + 2) / 2 + INSETS;
        wh               = size - 2 * INSETS - control.getBarWidth() - 2;
        startAngle       = -(150 - (360 - control.getRadialRange().ANGLE_RANGE) / 2);
        length           = control.getRadialRange().ANGLE_RANGE;
        barGradientStops = new Stop[] {
            new Stop(0, Color.TRANSPARENT),
            new Stop(0.8, control.getBarColor().darker()),
            new Stop(1.0, control.getBarColor().brighter())
        };
        alertIndicator   = createAlertIndicatorCanvas(control.getPrefWidth() * 0.165, control.getPrefHeight() * 0.135, control.getThresholdColor().COLOR);
        init();
    }


    // ******************** Initialization ************************************
    private void init() {
        if (control.getPrefWidth() < 0 | control.getPrefHeight() < 0) {
            control.setPrefSize(200, 200);
        }
        center = new Point2D(control.getPrefWidth() / 2, control.getPrefHeight() / 2);

        // Register listeners
        registerChangeListener(control.widthProperty(), "WIDTH");
        registerChangeListener(control.heightProperty(), "HEIGHT");
        registerChangeListener(control.prefWidthProperty(), "WIDTH");
        registerChangeListener(control.prefHeightProperty(), "HEIGHT");
        registerChangeListener(control.minWidthProperty(), "WIDTH");
        registerChangeListener(control.minHeightProperty(), "HEIGHT");
        registerChangeListener(control.maxWidthProperty(), "WIDTH");
        registerChangeListener(control.maxHeightProperty(), "HEIGHT");
        registerChangeListener(control.minValueProperty(), "FULL_REPAINT");
        registerChangeListener(control.maxValueProperty(), "FULL_REPAINT");
        registerChangeListener(control.gaugeModelProperty(), "FULL_REPAINT");
        registerChangeListener(control.barFrameColorProperty(), "FULL_REPAINT");
        registerChangeListener(control.barBackgroundColorProperty(), "FULL_REPAINT");
        registerChangeListener(control.valueLabelColorProperty(), "FULL_REPAINT");
        registerChangeListener(control.unitLabelColorProperty(), "FULL_REPAINT");
        registerChangeListener(control.unitProperty(), "FULL_REPAINT");
        registerChangeListener(control.barColorProperty(), "BAR");
        registerChangeListener(control.barWidthProperty(), "BAR");
        registerChangeListener(control.roundedBarProperty(), "BAR");
        registerChangeListener(control.valueLabelFontSizeProperty(), "LABEL");
        registerChangeListener(control.noOfDecimalsProperty(), "LABEL");
        registerChangeListener(control.minLabelColorProperty(), "MIN_MAX_LABEL");
        registerChangeListener(control.maxLabelColorProperty(), "MIN_MAX_LABEL");
        registerChangeListener(control.minMaxLabelFontSizeProperty(), "MIN_MAX_LABEL");
        registerChangeListener(control.valueProperty(), "VALUE");
        registerChangeListener(control.minLabelVisibleProperty(), "MIN_LABEL_VISIBLE");
        registerChangeListener(gaugeValue, "GAUGE_VALUE");

        valueText.setFill(control.getValueLabelColor());
        unitText.setFill(control.getUnitLabelColor());
        minLabel.setFill(control.getMinLabelColor());
        maxLabel.setFill(control.getMaxLabelColor());

        addBindings();

        updateNumberFormat();

        if (control.isCanvasMode()) {
            for (Section section : control.getSections()) {
                if ((gaugeValue.get() - control.getMinValue()) > section.getStart() && (gaugeValue.get() - control.getMinValue()) < section.getStop()) {
                    barGradientStops = new Stop[] {
                        new Stop(0, Color.TRANSPARENT),
                        new Stop(0.8, section.getColor().darker()),
                        new Stop(1.0, section.getColor().brighter())
                    };
                    break;
                } else {
                    barGradientStops = new Stop[] {
                        new Stop(0, Color.TRANSPARENT),
                        new Stop(0.8, control.getBarColor().darker()),
                        new Stop(1.0, control.getBarColor().brighter())
                    };
                }
            }
        }

        initialized = true;
        repaint();
    }

    private void addBindings() {
        // Don't show bar if value is smaller or equal minValue
        if (bar.visibleProperty().isBound()) {
            bar.visibleProperty().unbind();
        }
        bar.visibleProperty().bind(gaugeValue.greaterThan(control.minValueProperty()));

        if (minLabel.visibleProperty().isBound()) {
            minLabel.visibleProperty().unbind();
        }
        minLabel.visibleProperty().bind(control.minLabelVisibleProperty());

        if (maxLabel.visibleProperty().isBound()) {
            maxLabel.visibleProperty().unbind();
        }
        maxLabel.visibleProperty().bind(control.maxLabelVisibleProperty());
        
        if (valueText.visibleProperty().isBound()) {
            valueText.visibleProperty().unbind();
        }
        valueText.visibleProperty().bind(control.valueLabelVisibleProperty());

        if (unitText.visibleProperty().isBound()) {
            unitText.visibleProperty().unbind();
        }
        unitText.visibleProperty().bind(control.unitLabelVisibleProperty());

        if (valueText.fillProperty().isBound()) {
            valueText.fillProperty().unbind();
        }
        valueText.fillProperty().bind(control.valueLabelColorProperty());

        if (unitText.fillProperty().isBound()) {
            unitText.fillProperty().unbind();
        }
        unitText.fillProperty().bind(control.unitLabelColorProperty());
    }


    // ******************** Methods *******************************************
    @Override protected void handleControlPropertyChanged(final String PROPERTY) {
        super.handleControlPropertyChanged(PROPERTY);
        if ("WIDTH".equals(PROPERTY)) {
            recalcParameters();
            valueText.setLayoutX((size - valueText.getLayoutBounds().getWidth()) / 2);
            valueText.setLayoutY((size - valueText.getLayoutBounds().getHeight()) / 2 + control.getValueLabelFontSize());
            canvas.setWidth(size);
            canvas.setHeight(size);
            alertIndicator = createAlertIndicatorCanvas(control.getPrefWidth() * 0.165, control.getPrefHeight() * 0.135, control.getThresholdColor().COLOR);
            repaint();
        } else if ("HEIGHT".equals(PROPERTY)) {
            recalcParameters();
            valueText.setLayoutX((size - valueText.getLayoutBounds().getWidth()) / 2);
            valueText.setLayoutY((size - valueText.getLayoutBounds().getHeight()) / 2 + control.getValueLabelFontSize());
            canvas.setWidth(size);
            canvas.setHeight(size);
            alertIndicator = createAlertIndicatorCanvas(control.getPrefWidth() * 0.165, control.getPrefHeight() * 0.135, control.getThresholdColor().COLOR);
            repaint();
        } else if ("FULL_REPAINT".equals(PROPERTY)) {
            alertIndicator = createAlertIndicatorCanvas(control.getPrefWidth() * 0.165, control.getPrefHeight() * 0.135, control.getThresholdColor().COLOR);
            repaint();
        } else if ("VALUE".equals(PROPERTY)) {
            if (control.isValueAnimationEnabled()) {
                final KeyValue KEY_VALUE = new KeyValue(gaugeValue, control.getValue(), Interpolator.EASE_BOTH);
                final KeyFrame KEY_FRAME = new KeyFrame(Duration.millis(control.getTimeToValueInMs()), KEY_VALUE);
                timeline.setOnFinished(new EventHandler() {
                    @Override public void handle(ActionEvent actionEvent) {
                        gaugeValue.set(control.getValue());
                    }
                });
                timeline = new Timeline();
                timeline.getKeyFrames().add(KEY_FRAME);
                timeline.play();
            } else {
                gaugeValue.set(control.getValue());
            }
        } else if ("BAR".equals(PROPERTY)) {
            if (control.isCanvasMode()) {
                barGradientStops = new Stop[] {
                    new Stop(0, Color.TRANSPARENT),
                    new Stop(0.8, control.getBarColor().darker()),
                    new Stop(1.0, control.getBarColor().brighter())
                };
                drawCanvasGauge(ctx);
            } else {
                drawNodeGauge();
            }
        } else if ("LABEL".equals(PROPERTY)) {
            updateNumberFormat();
            repaint();
        } else if ("MIN_MAX_LABEL".equals(PROPERTY)) {
            minLabel.setFill(control.getMinLabelColor());
            minLabel.setFont(Font.font("Verdana", control.getMinMaxLabelFontSize()));
            maxLabel.setFill(control.getMaxLabelColor());
            maxLabel.setFont(Font.font("Verdana", control.getMinMaxLabelFontSize()));
            repaint();
        } else if ("GAUGE_VALUE".equals(PROPERTY)) {
            if (!control.getSections().isEmpty()) {
                for (Section section : control.getSections()) {
                    if ((gaugeValue.get() - control.getMinValue()) > section.getStart() && (gaugeValue.get() - control.getMinValue()) < section.getStop()) {
                        updateBarColor(section.getColor());
                        break;
                    } else {
                        updateBarColor(control.getBarColor());
                    }
                }
            }
            valueText.setText(valueFormat.format(gaugeValue.get()));
            valueText.setLayoutX((size - valueText.getLayoutBounds().getWidth()) / 2);
            valueText.setLayoutY((size - valueText.getLayoutBounds().getHeight()) / 2 + control.getValueLabelFontSize());
            bar.setLength(-gaugeValue.get() * control.getAngleStep());

            if (control.isThresholdBehaviorInverted() && gaugeValue.doubleValue() < control.getThreshold()) {
                control.setThresholdExceeded(true);
            } else if (!control.isThresholdBehaviorInverted() && gaugeValue.doubleValue() > control.getThreshold()) {
                control.setThresholdExceeded(true);
            } else {
                control.setThresholdExceeded(false);
            }
            alertIndicator.setVisible(control.isThresholdExceeded());

            if (control.isCanvasMode()) {
                for (Section section : control.getSections()) {
                    if ((gaugeValue.get() - control.getMinValue()) > section.getStart() && (gaugeValue.get() - control.getMinValue()) < section.getStop()) {
                        barGradientStops = new Stop[] {
                            new Stop(0, Color.TRANSPARENT),
                            new Stop(0.8, section.getColor().darker()),
                            new Stop(1.0, section.getColor().brighter())
                        };
                        break;
                    } else {
                        barGradientStops = new Stop[] {
                            new Stop(0, Color.TRANSPARENT),
                            new Stop(0.8, control.getBarColor().darker()),
                            new Stop(1.0, control.getBarColor().brighter())
                        };
                    }
                }
                drawCanvasGauge(ctx);
            }
        }
    }

    public final void repaint() {
        isDirty = true;
        requestLayout();
    }

    @Override public void layoutChildren() {
        if (!isDirty) {
            return;
        }
        if (!initialized) {
            init();
        }
        if (control.isCanvasMode()) {
            alertIndicator.setLayoutX((size - alertIndicator.getWidth()) * 0.5);
            alertIndicator.setLayoutY(size * 0.6);
            drawCanvasGauge(ctx);
            getChildren().setAll(canvas, alertIndicator);
        } else {
            drawNodeGauge();
            getChildren().setAll(gauge);
        }

        isDirty = false;

        super.layoutChildren();
    }

    @Override public final SimpleRadialGauge getSkinnable() {
        return control;
    }

    @Override public final void dispose() {
        control = null;
    }

    @Override protected double computePrefWidth(final double PREF_HEIGHT) {
        double prefWidth = 200;
        if (PREF_HEIGHT != -1) {
            prefWidth = Math.max(0, PREF_HEIGHT - getInsets().getLeft() - getInsets().getRight());
        }
        return super.computePrefWidth(prefWidth);
    }

    @Override protected double computePrefHeight(final double PREF_WIDTH) {
        double prefHeight = 200;
        if (PREF_WIDTH != -1) {
            prefHeight = Math.max(0, PREF_WIDTH - getInsets().getTop() - getInsets().getBottom());
        }
        return super.computePrefHeight(prefHeight);
    }

    @Override protected double computeMinWidth(final double MIN_HEIGHT) {
        return super.computeMinWidth(Math.max(50, MIN_HEIGHT - getInsets().getLeft() - getInsets().getRight()));
    }

    @Override protected double computeMinHeight(final double MIN_WIDTH) {
        return super.computeMinHeight(Math.max(50, MIN_WIDTH - getInsets().getTop() - getInsets().getBottom()));
    }

    @Override protected double computeMaxWidth(final double MAX_HEIGHT) {
        return super.computeMaxWidth(Math.max(200, MAX_HEIGHT - getInsets().getLeft() - getInsets().getRight()));
    }

    @Override protected double computeMaxHeight(final double MAX_WIDTH) {
        return super.computeMaxHeight(Math.max(200, MAX_WIDTH - getInsets().getTop() - getInsets().getBottom()));
    }

    private void updateNumberFormat() {
        StringBuilder noOfDecimals = new StringBuilder(5);
        if (control.getNoOfDecimals() == 0) {
            noOfDecimals.append("0");
        } else {
            noOfDecimals.append("0.");
            for (int i = 0 ; i < control.getNoOfDecimals() ; i++) {
                noOfDecimals.append("0");
            }
        }
        valueFormat = new DecimalFormat(noOfDecimals.toString(), new DecimalFormatSymbols(Locale.US));
    }

    private void updateBarColor(final Color BAR_COLOR) {
        final double RADIUS = size / 2 - 4;
        bar.setStroke(new RadialGradient(0, 0,
                                         center.getX(), center.getY(),
                                         RADIUS, false, CycleMethod.NO_CYCLE,
                                         new Stop(0.0, control.getBarColor()),
                                         new Stop((RADIUS - control.getBarWidth()) / RADIUS, Color.TRANSPARENT),
                                         new Stop((RADIUS - control.getBarWidth() + 1) / RADIUS, BAR_COLOR.darker()),
                                         new Stop((RADIUS - control.getBarWidth() / 2) / RADIUS, BAR_COLOR),
                                         new Stop(1.0, BAR_COLOR.deriveColor(0.85, 0.85, 0.85, 1))));
    }

    private void recalcParameters() {
        size             = control.getPrefWidth() < control.getPrefHeight() ? control.getPrefWidth() : control.getPrefHeight();
        xy               = (control.getBarWidth() + 2) / 2 + INSETS;
        wh               = size - 2 * INSETS - control.getBarWidth() - 2;
        length           = control.getRadialRange().ANGLE_RANGE;
        startAngle       = -(150 - (360 - length) / 2);
    }


    // ******************** Drawing related ***********************************
    private void drawNodeGauge() {
        size  = control.getPrefWidth() < control.getPrefHeight() ? control.getPrefWidth() : control.getPrefHeight();

        final double RADIUS     = size / 2 - 4;
        final double ARC_RADIUS = RADIUS - control.getBarWidth() / 2;
        center                  = new Point2D(size / 2, size / 2);

        gauge.getChildren().clear();

        final InnerShadow INNER_SHADOW = new InnerShadow();
        INNER_SHADOW.setRadius(0.01 * size);
        INNER_SHADOW.setBlurType(BlurType.GAUSSIAN);
        INNER_SHADOW.setColor(Color.rgb(0, 0, 0, 0.65));

        final InnerShadow INNER_GLOW = new InnerShadow();
        INNER_GLOW.setRadius(0.005 * size);
        INNER_GLOW.setBlurType(BlurType.GAUSSIAN);
        INNER_GLOW.setOffsetY(-1);
        INNER_GLOW.setColor(Color.color(1, 1, 1, 0.65));

        final Arc BAR_BACKGROUND = new Arc();
        BAR_BACKGROUND.setCenterX(center.getX());
        BAR_BACKGROUND.setCenterY(center.getY());
        BAR_BACKGROUND.setRadiusX(ARC_RADIUS);
        BAR_BACKGROUND.setRadiusY(ARC_RADIUS);
        BAR_BACKGROUND.setStartAngle(-(90 - (360 - control.getRadialRange().ANGLE_RANGE) / 2));
        BAR_BACKGROUND.setLength(control.getRadialRange().ANGLE_RANGE);
        BAR_BACKGROUND.setType(ArcType.OPEN);
        BAR_BACKGROUND.setFill(null);
        BAR_BACKGROUND.setSmooth(true);
        BAR_BACKGROUND.setStroke(control.getBarBackgroundColor());
        BAR_BACKGROUND.setStrokeWidth(control.getBarWidth());
        if (control.isRoundedBar()) {
            BAR_BACKGROUND.setStrokeLineCap(StrokeLineCap.ROUND);
        } else {
            BAR_BACKGROUND.setStrokeLineCap(StrokeLineCap.BUTT);
        }
        BAR_BACKGROUND.setEffect(INNER_SHADOW);

        bar.setCenterX(center.getX());
        bar.setCenterY(center.getY());
        bar.setRadiusX(BAR_BACKGROUND.getRadiusX());
        bar.setRadiusY(BAR_BACKGROUND.getRadiusY());
        bar.setStartAngle(control.getRadialRange().ANGLE_RANGE - (90 - (360 - control.getRadialRange().ANGLE_RANGE) / 2));
        bar.setLength(-gaugeValue.get() * control.getAngleStep());
        bar.setType(ArcType.OPEN);
        bar.setFill(null);
        bar.setSmooth(true);
        if (!control.getSections().isEmpty()) {
            for (Section section : control.getSections()) {
                if ((gaugeValue.get() - control.getMinValue()) > section.getStart() && (gaugeValue.get() - control.getMinValue()) < section.getStop()) {
                    updateBarColor(section.getColor());
                    break;
                } else {
                    updateBarColor(control.getBarColor());
                }
            }
        }
        if (control.isRoundedBar()) {
            bar.setStrokeLineCap(StrokeLineCap.ROUND);
        } else {
            bar.setStrokeLineCap(StrokeLineCap.BUTT);
        }
        bar.setStrokeWidth(control.getBarWidth());
        bar.setEffect(INNER_SHADOW);

        valueText.setFont(Font.font("Verdana", FontWeight.BOLD, control.getValueLabelFontSize()));
        //valueText.setFill(control.getValueLabelColor());
        valueText.setTextAlignment(TextAlignment.CENTER);
        valueText.setTextOrigin(VPos.BASELINE);
        valueText.setText(valueFormat.format(gaugeValue.get()));
        valueText.setLayoutX((size - valueText.getLayoutBounds().getWidth()) / 2);
        valueText.setLayoutY((size - valueText.getLayoutBounds().getHeight()) / 2 + control.getValueLabelFontSize());
        valueText.setEffect(INNER_GLOW);

        unitText.setFont(Font.font("Verdana", FontWeight.BOLD, control.getUnitLabelFontSize()));
        //unitText.setFill(control.getUnitLabelColor());
        unitText.setTextAlignment(TextAlignment.CENTER);
        unitText.setTextOrigin(VPos.BOTTOM);
        unitText.setText(control.getUnit());
        unitText.setLayoutX((size - unitText.getLayoutBounds().getWidth()) / 2);
        unitText.setLayoutY((size - unitText.getLayoutBounds().getHeight()));
        unitText.setEffect(INNER_GLOW);

        minLabel.setFont(Font.font("Verdana", FontWeight.NORMAL, control.getMinMaxLabelFontSize()));
        minLabel.setFill(control.getMinLabelColor());
        minLabel.setTextAlignment(TextAlignment.CENTER);
        minLabel.setTextOrigin(VPos.BOTTOM);
        minLabel.setText(valueFormat.format(control.getMinValue()));
        minLabel.setLayoutX(size * 0.025);
        minLabel.setLayoutY(size - minLabel.getLayoutBounds().getHeight() - (size * 0.025));

        maxLabel.setFont(Font.font("Verdana", FontWeight.NORMAL, control.getMinMaxLabelFontSize()));
        maxLabel.setFill(control.getMaxLabelColor());
        maxLabel.setTextAlignment(TextAlignment.CENTER);
        maxLabel.setTextOrigin(VPos.BOTTOM);
        maxLabel.setText(valueFormat.format(control.getMaxValue()));
        maxLabel.setLayoutX(size - maxLabel.getLayoutBounds().getWidth() - (size * 0.025));
        maxLabel.setLayoutY(size - maxLabel.getLayoutBounds().getHeight() - (size * 0.025));

        alertIndicator.setLayoutX((size - alertIndicator.getWidth()) * 0.5);
        alertIndicator.setLayoutY(size * 0.6);

        gauge.getChildren().addAll(BAR_BACKGROUND,
                                   bar,
                                   valueText,
                                   unitText,
                                   minLabel,
                                   maxLabel,
                                   alertIndicator);
        gauge.setCache(true);
        gauge.setCacheHint(CacheHint.QUALITY);
    }

    private void drawCanvasGauge(final GraphicsContext CTX) {
        //size  = control.getPrefWidth() < control.getPrefHeight() ? control.getPrefWidth() : control.getPrefHeight();

        //canvas.setWidth(size);
        //canvas.setHeight(size);

        //final double INSETS       = 4;
        //final double xy           = (control.getBarWidth() + 2) / 2 + INSETS;
        //final double wh           = size - 2 * INSETS - control.getBarWidth() - 2;
        //final double startAngle   = -(150 - (360 - control.getAngleRange()) / 2);
        //final double length       = control.getAngleRange();

        CTX.clearRect(0, 0, size, size);
        CTX.setStroke(control.getBarFrameColor());
        CTX.setLineWidth(control.getBarWidth() + 2);
        if (control.isRoundedBar()) {
            CTX.setLineCap(StrokeLineCap.ROUND);
        } else {
            CTX.setLineCap(StrokeLineCap.BUTT);
        }
        CTX.strokeArc(xy, xy, wh, wh, startAngle, -length, ArcType.OPEN);

        CTX.setStroke(control.getBarBackgroundColor());
        CTX.setLineWidth(control.getBarWidth());
        if (control.isRoundedBar()) {
            CTX.setLineCap(StrokeLineCap.ROUND);
        } else {
            CTX.setLineCap(StrokeLineCap.BUTT);
        }
        CTX.strokeArc(xy, xy, wh, wh, startAngle, -length, ArcType.OPEN);

        //CTX.setStroke(control.getBarColor());
        CTX.setStroke(new RadialGradient(0, 0,
                                         0.5 * size, 0.5 * size,
                                         0.5 * wh,
                                         false, CycleMethod.NO_CYCLE,
                                         barGradientStops));
        CTX.setLineWidth(control.getBarWidth());
        if (control.isRoundedBar()) {
            CTX.setLineCap(StrokeLineCap.ROUND);
        } else {
            CTX.setLineCap(StrokeLineCap.BUTT);
        }
        CTX.strokeArc(xy, xy, wh, wh, startAngle, -gaugeValue.doubleValue() * control.getAngleStep(), ArcType.OPEN);

        if (control.isValueLabelVisible()) {
            CTX.setFont(Font.font("Verdana", FontWeight.BOLD, control.getValueLabelFontSize()));
            CTX.setFill(control.getValueLabelColor());
            CTX.setTextAlign(TextAlignment.CENTER);
            CTX.setTextBaseline(VPos.CENTER);
            CTX.fillText(valueFormat.format(gaugeValue.doubleValue()), size / 2, size / 2);
        }

        if (control.isUnitLabelVisible() && !control.getUnit().isEmpty()) {
            CTX.setFont(Font.font("Verdana", FontWeight.BOLD, control.getUnitLabelFontSize()));
            CTX.setFill(control.getUnitLabelColor());
            CTX.setTextAlign(TextAlignment.CENTER);
            CTX.setTextBaseline(VPos.BOTTOM);
            CTX.fillText(control.getUnit(), size / 2, size - control.getUnitLabelFontSize());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy