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

eu.hansolo.medusa.skins.LcdSkin Maven / Gradle / Ivy

/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2016-2021 Gerrit Grunwald.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.hansolo.medusa.skins;

import eu.hansolo.medusa.Fonts;
import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.LcdDesign;
import eu.hansolo.medusa.LcdFont;
import eu.hansolo.medusa.Section;
import eu.hansolo.medusa.tools.Helper;
import javafx.beans.InvalidationListener;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.CacheHint;
import javafx.scene.Group;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.InnerShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Paint;
import javafx.scene.paint.Stop;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static eu.hansolo.medusa.tools.Helper.formatNumber;


/**
 * Created by hansolo on 21.01.16.
 */
public class LcdSkin extends GaugeSkinBase {
    protected static final double              PREFERRED_WIDTH    = 220;//275;
    protected static final double              PREFERRED_HEIGHT   = 100;
    protected static final double              MINIMUM_WIDTH      = 5;
    protected static final double              MINIMUM_HEIGHT     = 5;
    protected static final double              MAXIMUM_WIDTH      = 1024;
    protected static final double              MAXIMUM_HEIGHT     = 1024;
    private static final Color                 DARK_NOISE_COLOR   = Color.rgb(100, 100, 100, 0.10);
    private static final Color                 BRIGHT_NOISE_COLOR = Color.rgb(200, 200, 200, 0.05);
    private static final DropShadow            FOREGROUND_SHADOW  = new DropShadow();
    private static       double                aspectRatio        = 0.45454545;
    private static       Text                  oneSegment         = new Text("8");
    private static       Text                  dotSegment         = new Text(".");
    private              double                width;
    private              double                height;
    private              Pane                  pane;
    private              Paint                 lcdPaint;
    private              Paint                 lcdFramePaint;
    private              ImageView             crystalOverlay;
    private              Image                 crystalImage;
    private              Rectangle             crystalClip;
    private              InnerShadow           mainInnerShadow0;
    private              InnerShadow           mainInnerShadow1;
    private              Path                  threshold;
    private              Path                  average;
    private              Text                  valueText;
    private              Text                  backgroundText;
    private              Text                  unitText;
    private              Text                  title;
    private              Text                  lowerRightText;
    private              Text                  upperLeftText;
    private              Text                  upperRightText;
    private              Text                  lowerCenterText;
    private              double                valueOffsetLeft;
    private              double                valueOffsetRight;
    private              double                digitalFontSizeFactor;
    private              Font                  valueFont;
    private              Font                  unitFont;
    private              Font                  titleFont;
    private              Font                  smallFont;
    private              double                oneSegmentWidth;
    private              double                dotSegmentWidth;
    private              double                widthOfDecimals;
    private              double                availableWidth;
    private              int                   noOfSegments;
    private              StringBuilder         backgroundTextBuilder;
    private              Group                 shadowGroup;
    private              String                valueFormatString;
    private              String                otherFormatString;
    private              Locale                locale;
    private              List
sections; private Map sectionColorMap; private InvalidationListener currentValueListener; // ******************** Constructors ************************************** public LcdSkin(Gauge gauge) { super(gauge); width = PREFERRED_WIDTH; height = PREFERRED_HEIGHT; valueOffsetLeft = 0.0; valueOffsetRight = 0.0; digitalFontSizeFactor = 1.0; backgroundTextBuilder = new StringBuilder(); valueFormatString = new StringBuilder("%.").append(gauge.getDecimals()).append("f").toString(); otherFormatString = new StringBuilder("%.").append(gauge.getTickLabelDecimals()).append("f").toString(); locale = gauge.getLocale(); sections = gauge.getSections(); sectionColorMap = new HashMap<>(sections.size()); currentValueListener = o -> handleEvents("REDRAW"); updateSectionColors(); FOREGROUND_SHADOW.setOffsetX(0); FOREGROUND_SHADOW.setOffsetY(1); FOREGROUND_SHADOW.setColor(Color.rgb(0, 0, 0, 0.5)); FOREGROUND_SHADOW.setBlurType(BlurType.TWO_PASS_BOX); FOREGROUND_SHADOW.setRadius(2); initGraphics(); registerListeners(); } // ******************** Initialization ************************************ 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); } } mainInnerShadow0 = new InnerShadow(); mainInnerShadow0.setOffsetX(0.0); mainInnerShadow0.setOffsetY(0.0); mainInnerShadow0.setRadius(0.0625 * PREFERRED_HEIGHT); mainInnerShadow0.setColor(Color.rgb(255, 255, 255, 0.5)); mainInnerShadow0.setBlurType(BlurType.TWO_PASS_BOX); mainInnerShadow1 = new InnerShadow(); mainInnerShadow1.setOffsetX(0.0); mainInnerShadow1.setOffsetY(1.0); mainInnerShadow1.setRadius(0.04166667 * PREFERRED_HEIGHT); mainInnerShadow1.setColor(Color.rgb(0, 0, 0, 0.65)); mainInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX); mainInnerShadow1.setInput(mainInnerShadow0); crystalClip = new Rectangle(0, 0, width, height); crystalClip.setArcWidth(5); crystalClip.setArcHeight(5); crystalImage = Helper.createNoiseImage(PREFERRED_WIDTH, PREFERRED_HEIGHT, DARK_NOISE_COLOR, BRIGHT_NOISE_COLOR, 8); crystalOverlay = new ImageView(crystalImage); crystalOverlay.setClip(crystalClip); boolean crystalEnabled = gauge.isLcdCrystalEnabled(); Helper.enableNode(crystalOverlay, crystalEnabled); threshold = new Path(); threshold.setStroke(null); Helper.enableNode(threshold, gauge.isThresholdVisible()); average = new Path(); average.setStroke(null); Helper.enableNode(average, gauge.isAverageVisible()); backgroundText = new Text(String.format(locale, valueFormatString, gauge.getCurrentValue())); backgroundText.setFill(gauge.getLcdDesign().lcdBackgroundColor); backgroundText.setOpacity((LcdFont.LCD == gauge.getLcdFont() || LcdFont.ELEKTRA == gauge.getLcdFont()) ? 1 : 0); valueText = new Text(String.format(locale, valueFormatString, gauge.getCurrentValue())); valueText.setFill(gauge.getLcdDesign().lcdForegroundColor); unitText = new Text(gauge.getUnit()); unitText.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(unitText, !gauge.getUnit().isEmpty()); title = new Text(gauge.getTitle()); title.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(title, !gauge.getTitle().isEmpty()); lowerRightText = new Text(gauge.getSubTitle()); lowerRightText.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(lowerRightText, !gauge.getSubTitle().isEmpty()); upperLeftText = new Text(String.format(locale, otherFormatString, gauge.getMinMeasuredValue())); upperLeftText.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(upperLeftText, gauge.isMinMeasuredValueVisible()); upperRightText = new Text(String.format(locale, otherFormatString, gauge.getMaxMeasuredValue())); upperRightText.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(upperRightText, gauge.isMaxMeasuredValueVisible()); lowerCenterText = new Text(String.format(locale, otherFormatString, gauge.getOldValue())); lowerCenterText.setFill(gauge.getLcdDesign().lcdForegroundColor); Helper.enableNode(lowerCenterText, gauge.isOldValueVisible()); shadowGroup = new Group(); shadowGroup.setEffect(gauge.isShadowsEnabled() ? FOREGROUND_SHADOW : null); shadowGroup.getChildren().setAll(threshold, average, valueText, unitText, title, lowerRightText, upperLeftText, upperRightText, lowerCenterText); pane = new Pane(crystalOverlay, backgroundText, shadowGroup); pane.setEffect(gauge.isShadowsEnabled() ? mainInnerShadow1 : null); getChildren().setAll(pane); } @Override protected void registerListeners() { super.registerListeners(); gauge.currentValueProperty().addListener(currentValueListener); } // ******************** Methods ******************************************* @Override protected void handleEvents(final String EVENT_TYPE) { if ("REDRAW".equals(EVENT_TYPE)) { pane.setEffect(gauge.isShadowsEnabled() ? mainInnerShadow1 : null); shadowGroup.setEffect(gauge.isShadowsEnabled() ? FOREGROUND_SHADOW : null); updateLcdDesign(height); redraw(); } else if ("RESIZE".equals(EVENT_TYPE)) { aspectRatio = gauge.getPrefHeight() / gauge.getPrefWidth(); resize(); redraw(); } else if ("LCD".equals(EVENT_TYPE)) { updateLcdDesign(height); } else if ("VISIBILITY".equals(EVENT_TYPE)) { Helper.enableNode(crystalOverlay, gauge.isLcdCrystalEnabled()); Helper.enableNode(title, !gauge.getTitle().isEmpty()); Helper.enableNode(unitText, !gauge.getUnit().isEmpty()); Helper.enableNode(upperLeftText, gauge.isMinMeasuredValueVisible()); Helper.enableNode(upperRightText, gauge.isMaxMeasuredValueVisible()); Helper.enableNode(lowerRightText, !gauge.getSubTitle().isEmpty()); Helper.enableNode(lowerCenterText, gauge.isOldValueVisible()); Helper.enableNode(average, gauge.isAverageVisible()); Helper.enableNode(threshold, gauge.isThresholdVisible()); resize(); redraw(); } else if ("SECTION".equals(EVENT_TYPE)) { sections = gauge.getSections(); updateSectionColors(); resize(); redraw(); } } @Override public void dispose() { gauge.currentValueProperty().removeListener(currentValueListener); super.dispose(); } // ******************** Private Methods *********************************** private boolean isNoOfDigitsInvalid() { final double AVAILABLE_WIDTH = width - 2 - valueOffsetLeft - valueOffsetRight; final double NEEDED_WIDTH = valueText.getLayoutBounds().getWidth(); return Double.compare(AVAILABLE_WIDTH, NEEDED_WIDTH) < 0; } private void updateLcdDesign(final double HEIGHT) { LcdDesign lcdDesign = gauge.getLcdDesign(); Color[] lcdColors = lcdDesign.getColors(); if (LcdDesign.SECTIONS == lcdDesign) { double currentValue = gauge.getCurrentValue(); int listSize = sections.size(); for (int i = 0 ; i < listSize ; i++) { Section section = sections.get(i); if (section.contains(currentValue)) { lcdColors = sectionColorMap.get(section); break; } } } lcdPaint = new LinearGradient(0, 1, 0, HEIGHT - 1, false, CycleMethod.NO_CYCLE, new Stop(0, lcdColors[0]), new Stop(0.03, lcdColors[1]), new Stop(0.5, lcdColors[2]), new Stop(0.5, lcdColors[3]), new Stop(1.0, lcdColors[4])); if (lcdDesign.name().startsWith("FLAT")) { lcdFramePaint = gauge.getBorderPaint(); lcdPaint = gauge.getBackgroundPaint(); Color lcdForegroundColor = (Color) gauge.getForegroundPaint(); backgroundText.setFill(Color.color(lcdForegroundColor.getRed(), lcdForegroundColor.getGreen(), lcdForegroundColor.getBlue(), 0.1)); valueText.setFill(lcdForegroundColor); upperLeftText.setFill(lcdForegroundColor); title.setFill(lcdForegroundColor); upperRightText.setFill(lcdForegroundColor); unitText.setFill(lcdForegroundColor); lowerRightText.setFill(lcdForegroundColor); lowerCenterText.setFill(lcdForegroundColor); threshold.setFill(lcdForegroundColor); average.setFill(lcdForegroundColor); } else { lcdFramePaint = new LinearGradient(0, 0.02083333 * height, 0, HEIGHT - 0.02083333 * HEIGHT, false, CycleMethod.NO_CYCLE, new Stop(0.0, Color.rgb(26, 26, 26)), new Stop(0.015, Color.rgb(77, 77, 77)), new Stop(0.985, Color.rgb(77, 77, 77)), new Stop(1.0, Color.rgb(221, 221, 221))); lcdPaint = new LinearGradient(0, 1, 0, HEIGHT - 1, false, CycleMethod.NO_CYCLE, new Stop(0, lcdColors[0]), new Stop(0.03, lcdColors[1]), new Stop(0.5, lcdColors[2]), new Stop(0.5, lcdColors[3]), new Stop(1.0, lcdColors[4])); backgroundText.setFill(lcdDesign.lcdBackgroundColor); valueText.setFill(lcdDesign.lcdForegroundColor); upperLeftText.setFill(lcdDesign.lcdForegroundColor); title.setFill(lcdDesign.lcdForegroundColor); upperRightText.setFill(lcdDesign.lcdForegroundColor); unitText.setFill(lcdDesign.lcdForegroundColor); lowerRightText.setFill(lcdDesign.lcdForegroundColor); lowerCenterText.setFill(lcdDesign.lcdForegroundColor); threshold.setFill(lcdDesign.lcdForegroundColor); average.setFill(lcdDesign.lcdForegroundColor); } pane.setBackground(new Background(new BackgroundFill(lcdPaint, new CornerRadii(0.10416667 * HEIGHT), Insets.EMPTY))); pane.setBorder(new Border(new BorderStroke(lcdFramePaint, BorderStrokeStyle.SOLID, new CornerRadii(0.05 * HEIGHT), new BorderWidths(0.02083333 * HEIGHT)))); } private void updateSectionColors() { int listSize = sections.size(); sectionColorMap.clear(); for (int i = 0 ; i < listSize ; i++) { Color sectionColor = sections.get(i).getColor(); Color lcdForegroundColor; if (Helper.isMonochrome(sectionColor)) { lcdForegroundColor = Helper.isDark(sectionColor) ? Color.WHITE : Color.BLACK; } else { lcdForegroundColor = Color.hsb(sectionColor.getHue(), sectionColor.getSaturation(), sectionColor.getBrightness() * 0.3); } Color lcdBackgroundColor = Color.color(sectionColor.getRed(), sectionColor.getGreen(), sectionColor.getBlue(), 0.1); sectionColorMap.put(sections.get(i), getSectionColors(lcdBackgroundColor, lcdForegroundColor)); } } private Color[] getSectionColors(final Color LCD_BACKGROUND_COLOR, final Color LCD_FOREGROUND_COLOR) { double hue = LCD_BACKGROUND_COLOR.getHue(); double sat = LCD_BACKGROUND_COLOR.getSaturation(); Color[] colors; if (Helper.isMonochrome(LCD_BACKGROUND_COLOR)) { // Section color is monochrome colors = new Color[]{ Color.hsb(hue, 0, 0.69), Color.hsb(hue, 0, 1.0), Color.hsb(hue, 0, 0.76), Color.hsb(hue, 0, 0.76), Color.hsb(hue, sat, 0.69), Helper.isDark(LCD_BACKGROUND_COLOR) ? Color.WHITE : Color.BLACK, Helper.isDark(LCD_BACKGROUND_COLOR) ? Color.rgb(255, 255, 255, 0.1) : Color.rgb(0, 0, 0, 0.1) }; } else { // Section color is not monochrome colors = new Color[]{ Color.hsb(hue, sat, 0.69), Color.hsb(hue, sat, 1.0), Color.hsb(hue, sat, 0.76), Color.hsb(hue, sat, 0.76), Color.hsb(hue, sat, 0.69), LCD_FOREGROUND_COLOR, Color.color(LCD_BACKGROUND_COLOR.getRed(), LCD_BACKGROUND_COLOR.getGreen(), LCD_BACKGROUND_COLOR.getBlue(), 0.1) }; } return colors; } private void updateFonts() { digitalFontSizeFactor = 1.0; switch(gauge.getLcdFont()) { case LCD: valueFont = Fonts.digital(0.6 * height); digitalFontSizeFactor = 1.4; break; case DIGITAL: valueFont = Fonts.digitalReadout(0.5833333333 * height); break; case DIGITAL_BOLD: valueFont = Fonts.digitalReadoutBold(0.5833333333 * height); break; case ELEKTRA: valueFont = Fonts.elektra(0.62 * height); break; case STANDARD: default: valueFont = Fonts.robotoMedium(0.5 * height); break; } backgroundText.setFont(valueFont); backgroundText.setOpacity((LcdFont.LCD == gauge.getLcdFont() || LcdFont.DIGITAL == gauge.getLcdFont() || LcdFont.DIGITAL_BOLD == gauge.getLcdFont() || LcdFont.ELEKTRA == gauge.getLcdFont()) ? 1 : 0); valueText.setFont(valueFont); unitFont = Fonts.latoBold(0.26 * height); titleFont = Fonts.latoBold(0.1666666667 * height); smallFont = Fonts.latoBold(0.1666666667 * height); } private void updateBackgroundText() { // Setup the semitransparent background text backgroundText.setCache(false); backgroundText.setTextOrigin(VPos.BASELINE); backgroundText.setTextAlignment(TextAlignment.RIGHT); // Setup the semitransparent background text // Width of one segment oneSegment.setFont(valueFont); dotSegment.setText("."); if (LcdFont.LCD == gauge.getLcdFont()) { oneSegment.setText("8"); } else if (LcdFont.DIGITAL == gauge.getLcdFont()) { oneSegment.setText("_"); } else if (LcdFont.DIGITAL_BOLD == gauge.getLcdFont()) { oneSegment.setText("_"); } else if (LcdFont.ELEKTRA == gauge.getLcdFont()) { oneSegment.setText("_"); } oneSegmentWidth = oneSegment.getLayoutBounds().getWidth(); dotSegmentWidth = dotSegment.getLayoutBounds().getWidth(); // Width of decimals widthOfDecimals = 0 == gauge.getDecimals() ? 0 : gauge.getDecimals() * oneSegmentWidth + (LcdFont.LCD == gauge.getLcdFont() ? oneSegmentWidth : dotSegmentWidth); // Available width availableWidth = width - (0.0151515152 * width) - (0.0416666667 * height) - 2 - valueOffsetRight - widthOfDecimals; // Number of segments noOfSegments = (int) Math.floor(availableWidth / oneSegmentWidth); // Add segments to background text backgroundTextBuilder.setLength(0); for (int i = 0 ; i < gauge.getDecimals() ; i++) { backgroundTextBuilder.append(oneSegment.getText()); } if (gauge.getDecimals() != 0) { backgroundTextBuilder.insert(0, "."); } for (int i = 0 ; i < noOfSegments ; i++) { backgroundTextBuilder.insert(0, oneSegment.getText()); } backgroundText.setText(backgroundTextBuilder.toString()); backgroundText.setCache(true); backgroundText.setCacheHint(CacheHint.SCALE); } @Override protected void resize() { width = gauge.getWidth() - gauge.getInsets().getLeft() - gauge.getInsets().getRight(); height = gauge.getHeight() - gauge.getInsets().getTop() - gauge.getInsets().getBottom(); if (aspectRatio * width > height) { width = 1 / (aspectRatio / height); } else if (1 / (aspectRatio / height) > width) { height = aspectRatio * width; } if (width > 0 && height > 0) { pane.setMaxSize(width, height); pane.relocate((gauge.getWidth() - width) * 0.5, (gauge.getHeight() - height) * 0.5); updateLcdDesign(height); mainInnerShadow0.setRadius(0.0625 * height); mainInnerShadow1.setRadius(0.04166667 * height); if (crystalOverlay.isVisible()) { double frameWidth = 0.02083333 * height; double imgWidth = width - (2 * frameWidth); double imgHeight = height - (2 * frameWidth); crystalClip.setWidth(imgWidth); crystalClip.setHeight(imgHeight); crystalOverlay.setImage(Helper.createNoiseImage(width, height, DARK_NOISE_COLOR, BRIGHT_NOISE_COLOR, 8)); crystalOverlay.setCache(true); crystalOverlay.relocate(frameWidth, frameWidth); } double tSize = 0.2 * height; threshold.getElements().clear(); threshold.getElements().add(new MoveTo(0.41666667 * tSize, 0.75 * tSize)); threshold.getElements().add(new LineTo(0.583333333333333 * tSize, 0.75 * tSize)); threshold.getElements().add(new LineTo(0.583333333333333 * tSize, 0.916666666666667 * tSize)); threshold.getElements().add(new LineTo(0.416666666666667 * tSize, 0.916666666666667 * tSize)); threshold.getElements().add(new LineTo(0.416666666666667 * tSize, 0.75 * tSize)); threshold.getElements().add(new ClosePath()); threshold.getElements().add(new MoveTo(0.416666666666667 * tSize, 0.333333333333333 * tSize)); threshold.getElements().add(new LineTo(0.583333333333333 * tSize, 0.333333333333333 * tSize)); threshold.getElements().add(new LineTo(0.583333333333333 * tSize, 0.666666666666667 * tSize)); threshold.getElements().add(new LineTo(0.416666666666667 * tSize, 0.666666666666667 * tSize)); threshold.getElements().add(new LineTo(0.416666666666667 * tSize, 0.333333333333333 * tSize)); threshold.getElements().add(new ClosePath()); threshold.getElements().add(new MoveTo(tSize, tSize)); threshold.getElements().add(new LineTo(0.5 * tSize, 0)); threshold.getElements().add(new LineTo(0, tSize)); threshold.getElements().add(new LineTo(tSize, tSize)); threshold.getElements().add(new ClosePath()); threshold.relocate(0.027961994662429348 * width, 0.75 * height); double aSize = 0.12 * height; average.getElements().clear(); average.getElements().add(new MoveTo(0.5 * aSize, 0.0)); average.getElements().add(new CubicCurveTo(0.22727272727272727 * aSize, 0.0, 0.022727272727272728 * aSize, 0.22727272727272727 * aSize, 0.022727272727272728 * aSize, 0.5 * aSize)); average.getElements().add(new CubicCurveTo(0.022727272727272728 * aSize, 0.6136363636363636 * aSize, 0.045454545454545456 * aSize, 0.7045454545454546 * aSize, 0.11363636363636363 * aSize, 0.7954545454545454 * aSize)); average.getElements().add(new CubicCurveTo(0.11363636363636363 * aSize, 0.7954545454545454 * aSize, 0.0, 0.8863636363636364 * aSize, 0.0, 0.8863636363636364 * aSize)); average.getElements().add(new LineTo(0.09090909090909091 * aSize, 0.9772727272727273 * aSize)); average.getElements().add(new CubicCurveTo(0.09090909090909091 * aSize, 0.9772727272727273 * aSize, 0.18181818181818182 * aSize, 0.8863636363636364 * aSize, 0.18181818181818182 * aSize, 0.8863636363636364 * aSize)); average.getElements().add(new CubicCurveTo(0.2727272727272727 * aSize, 0.9545454545454546 * aSize, 0.38636363636363635 * aSize, aSize, 0.5 * aSize, aSize)); average.getElements().add(new CubicCurveTo(0.7727272727272727 * aSize, aSize, 0.9772727272727273 * aSize, 0.7727272727272727 * aSize, 0.9772727272727273 * aSize, 0.5 * aSize)); average.getElements().add(new CubicCurveTo(0.9772727272727273 * aSize, 0.38636363636363635 * aSize, 0.9545454545454546 * aSize, 0.29545454545454547 * aSize, 0.8863636363636364 * aSize, 0.20454545454545456 * aSize)); average.getElements().add(new CubicCurveTo(0.8863636363636364 * aSize, 0.20454545454545456 * aSize, aSize, 0.09090909090909091 * aSize, aSize, 0.09090909090909091 * aSize)); average.getElements().add(new LineTo(0.9090909090909091 * aSize, 0.0)); average.getElements().add(new CubicCurveTo(0.9090909090909091 * aSize, 0.0, 0.7954545454545454 * aSize, 0.09090909090909091 * aSize, 0.7954545454545454 * aSize, 0.09090909090909091 * aSize)); average.getElements().add(new CubicCurveTo(0.7045454545454546 * aSize, 0.045454545454545456 * aSize, 0.6136363636363636 * aSize, 0.0, 0.5 * aSize, 0.0)); average.getElements().add(new ClosePath()); average.getElements().add(new MoveTo(0.7954545454545454 * aSize, 0.29545454545454547 * aSize)); average.getElements().add(new CubicCurveTo(0.8181818181818182 * aSize, 0.36363636363636365 * aSize, 0.8409090909090909 * aSize, 0.4318181818181818 * aSize, 0.8409090909090909 * aSize, 0.5 * aSize)); average.getElements().add(new CubicCurveTo(0.8409090909090909 * aSize, 0.7045454545454546 * aSize, 0.7045454545454546 * aSize, 0.8863636363636364 * aSize, 0.5 * aSize, 0.8863636363636364 * aSize)); average.getElements().add(new CubicCurveTo(0.4090909090909091 * aSize, 0.8863636363636364 * aSize, 0.3409090909090909 * aSize, 0.8636363636363636 * aSize, 0.2727272727272727 * aSize, 0.7954545454545454 * aSize)); average.getElements().add(new CubicCurveTo(0.2727272727272727 * aSize, 0.7954545454545454 * aSize, 0.7954545454545454 * aSize, 0.29545454545454547 * aSize, 0.7954545454545454 * aSize, 0.29545454545454547 * aSize)); average.getElements().add(new ClosePath()); average.getElements().add(new MoveTo(0.5 * aSize, 0.11363636363636363 * aSize)); average.getElements().add(new CubicCurveTo(0.5909090909090909 * aSize, 0.11363636363636363 * aSize, 0.6590909090909091 * aSize, 0.13636363636363635 * aSize, 0.7045454545454546 * aSize, 0.18181818181818182 * aSize)); average.getElements().add(new CubicCurveTo(0.7045454545454546 * aSize, 0.18181818181818182 * aSize, 0.20454545454545456 * aSize, 0.6818181818181818 * aSize, 0.20454545454545456 * aSize, 0.6818181818181818 * aSize)); average.getElements().add(new CubicCurveTo(0.18181818181818182 * aSize, 0.6363636363636364 * aSize, 0.1590909090909091 * aSize, 0.5681818181818182 * aSize, 0.1590909090909091 * aSize, 0.5 * aSize)); average.getElements().add(new CubicCurveTo(0.1590909090909091 * aSize, 0.29545454545454547 * aSize, 0.29545454545454547 * aSize, 0.11363636363636363 * aSize, 0.5 * aSize, 0.11363636363636363 * aSize)); average.getElements().add(new ClosePath()); average.relocate(0.32 * width, 0.82 * height); updateFonts(); // Setup the lcd unit unitText.setFont(unitFont); unitText.setTextOrigin(VPos.BASELINE); unitText.setTextAlignment(TextAlignment.RIGHT); unitText.setText(gauge.getUnit()); if (unitText.visibleProperty().isBound()) { unitText.visibleProperty().unbind(); } valueOffsetLeft = height * 0.04; if (gauge.getUnit().isEmpty()) { valueOffsetRight = height * 0.0833333333; valueText.setX((width - valueText.getLayoutBounds().getWidth()) - valueOffsetRight); } else { unitText.setX((width - unitText.getLayoutBounds().getWidth()) - height * 0.04); unitText.setY(height - (valueText.getLayoutBounds().getHeight() * digitalFontSizeFactor) * 0.5); valueOffsetRight = (unitText.getLayoutBounds().getWidth() + height * 0.0833333333); // distance between value and unit valueText.setX(width - 2 - valueText.getLayoutBounds().getWidth() - valueOffsetRight); } valueText.setY(height - (valueText.getLayoutBounds().getHeight() * digitalFontSizeFactor) * 0.5); // Visualize the lcd semitransparent background text updateBackgroundText(); if (gauge.getUnit().isEmpty()) { backgroundText.setX((width - backgroundText.getLayoutBounds().getWidth()) - valueOffsetRight); } else { backgroundText.setX(width - 2 - backgroundText.getLayoutBounds().getWidth() - valueOffsetRight); } backgroundText.setY(height - (backgroundText.getLayoutBounds().getHeight() * digitalFontSizeFactor) * 0.5); // Setup the font for the lcd title, number system, min measured, max measure and former value // Title title.setFont(titleFont); title.setTextOrigin(VPos.BASELINE); title.setTextAlignment(TextAlignment.CENTER); title.setText(gauge.getTitle()); title.setX((width - title.getLayoutBounds().getWidth()) * 0.5); title.setY(height * 0.18); // Lower Right Text lowerRightText.setFont(smallFont); lowerRightText.setTextOrigin(VPos.BASELINE); lowerRightText.setTextAlignment(TextAlignment.RIGHT); lowerRightText.setText(gauge.getSubTitle()); lowerRightText.setX(pane.getLayoutBounds().getMinX() + (pane.getLayoutBounds().getWidth() - lowerRightText.getLayoutBounds().getWidth()) * 0.5); lowerRightText.setY(height * 0.94); // Min measured value upperLeftText.setFont(smallFont); upperLeftText.setTextOrigin(VPos.BASELINE); upperLeftText.setTextAlignment(TextAlignment.RIGHT); upperLeftText.setX(pane.getLayoutBounds().getMinX() + 0.0416666667 * height); upperLeftText.setY(height * 0.18); // Max measured value upperRightText.setFont(smallFont); upperRightText.setTextOrigin(VPos.BASELINE); upperRightText.setTextAlignment(TextAlignment.RIGHT); upperRightText.setY(height * 0.18); // Lower Center Text lowerCenterText.setFont(smallFont); lowerCenterText.setTextOrigin(VPos.BASELINE); lowerCenterText.setTextAlignment(TextAlignment.CENTER); lowerCenterText.setX((width - lowerCenterText.getLayoutBounds().getWidth()) * 0.5); lowerCenterText.setY(height * 0.94); } } @Override protected void redraw() { locale = gauge.getLocale(); valueFormatString = new StringBuilder("%.").append(gauge.getDecimals()).append("f").toString(); otherFormatString = new StringBuilder("%.").append(gauge.getTickLabelDecimals()).append("f").toString(); if (gauge.isThresholdVisible()) { threshold.setVisible(Double.compare(gauge.getCurrentValue(), gauge.getThreshold()) >= 0); } //valueText.setText(isNoOfDigitsInvalid() ? "-E-" : formatNumber(gauge.getLocale(), gauge.getFormatString(), gauge.getDecimals(), gauge.getCurrentValue())); valueText.setText(isNoOfDigitsInvalid() ? "-E-" : String.format(Locale.US, valueFormatString, gauge.getCurrentValue())); updateBackgroundText(); // Visualize the lcd semitransparent background text if (gauge.getUnit().isEmpty()) { backgroundText.setX((width - backgroundText.getLayoutBounds().getWidth()) - valueOffsetRight); } else { backgroundText.setX(width - 2 - backgroundText.getLayoutBounds().getWidth() - valueOffsetRight); } backgroundText.setY(height - (backgroundText.getLayoutBounds().getHeight() * digitalFontSizeFactor) * 0.5); if (gauge.getUnit().isEmpty()) { valueText.setX((width - valueText.getLayoutBounds().getWidth()) - valueOffsetRight); } else { valueText.setX((width - 2 - valueText.getLayoutBounds().getWidth()) - valueOffsetRight); } // Update the title title.setText(gauge.getTitle()); title.setX((width - title.getLayoutBounds().getWidth()) * 0.5); // Update the upper left text upperLeftText.setText(String.format(locale, otherFormatString, gauge.getMinMeasuredValue())); if (upperLeftText.getX() + upperLeftText.getLayoutBounds().getWidth() > title.getX()) { upperLeftText.setText("..."); } // Update the upper right text upperRightText.setText(String.format(locale, otherFormatString, gauge.getMaxMeasuredValue())); upperRightText.setX(width - upperRightText.getLayoutBounds().getWidth() - 0.0416666667 * height); if (upperRightText.getX() < title.getX() + title.getLayoutBounds().getWidth()) { upperRightText.setText("..."); upperRightText.setX(width - upperRightText.getLayoutBounds().getWidth() - 0.0416666667 * height); } // Update the lower center text if (gauge.isAverageVisible()) { lowerCenterText.setText(String.format(locale, otherFormatString, gauge.getAverage())); } else { lowerCenterText.setText(String.format(locale, otherFormatString, gauge.getOldValue())); } lowerCenterText.setX((width - lowerCenterText.getLayoutBounds().getWidth()) * 0.5); lowerCenterText.setY(0.94 * height); average.relocate(lowerCenterText.getX() - 0.2 * height, 0.82 * height); // Update the lower right text lowerRightText.setText(gauge.getSubTitle()); lowerRightText.setX(width - lowerRightText.getLayoutBounds().getWidth() - 0.0416666667 * height); lowerRightText.setY(height * 0.94); if (lowerRightText.getX() < lowerCenterText.getX() + lowerCenterText.getLayoutBounds().getWidth()) { lowerRightText.setText("..."); lowerRightText.setX(width - lowerRightText.getLayoutBounds().getWidth() - 0.0416666667 * height); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy