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

io.fair_acc.chartfx.plugins.measurements.utils.CheckedValueField Maven / Gradle / Ivy

package io.fair_acc.chartfx.plugins.measurements.utils;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;

import io.fair_acc.chartfx.utils.FXUtils;

/**
 * @author rstein
 */
public class CheckedValueField extends VBox {
    private static final String DEFAULT_FONT_DATASET = "Verdana Bold";
    private static final String DEFAULT_FONT = "Verdana Bold";
    private static final String DEFAULT_UNIT_FONT = "Verdana Bold";
    private static final int DEFAULT_FONT_SIZE = 550;
    private static final int DEFAULT_UNIT_FONT_SIZE = 300;
    private static final double FONT_SCALE = 3000.0;
    private static final int DEFAULT_MIN_FONT_SIZE = 18;

    private static final int DEFAULT_MIN_UNIT_FONT_SIZE = 14;
    private final DoubleProperty value = new SimpleDoubleProperty(this, "value", Double.NaN);
    private final DoubleProperty minRange = new SimpleDoubleProperty(this, "minRange", Double.NEGATIVE_INFINITY);
    private final DoubleProperty maxRange = new SimpleDoubleProperty(this, "maxRange", Double.POSITIVE_INFINITY);

    private final Label valueLabel = new Label();
    private final Label unitLabel = new Label();
    protected final Label dataSetName = new Label();
    protected CheckedNumberTextField dataRangeMin = new CheckedNumberTextField(minRange.get());
    protected CheckedNumberTextField dataRangeMax = new CheckedNumberTextField(maxRange.get());
    protected final ChangeListener minRangeFocusLost = (ch, o, n) -> evaluateMinRangeText(true);
    protected final ChangeListener maxRangeFocusLost = (ch, o, n) -> evaluateMaxRangeText(true);
    protected final EventHandler minRangeTyped = ke -> {
        if (ke.getCode().equals(KeyCode.ENTER)) {
            evaluateMinRangeText(false);
        }
    };
    protected final EventHandler maxRangeTyped = ke -> {
        if (ke.getCode().equals(KeyCode.ENTER)) {
            evaluateMaxRangeText(false);
        }
    };
    protected final ChangeListener widthChangeListener = (obs, o, n) -> {
        final double fontSizeLarge = Math.max(CheckedValueField.DEFAULT_MIN_FONT_SIZE,
                Math.min(CheckedValueField.DEFAULT_FONT_SIZE,
                        n.doubleValue() / FONT_SCALE * CheckedValueField.DEFAULT_FONT_SIZE));
        final double fontSizeSmall = Math.max(CheckedValueField.DEFAULT_MIN_UNIT_FONT_SIZE,
                Math.min(CheckedValueField.DEFAULT_UNIT_FONT_SIZE,
                        n.doubleValue() / FONT_SCALE * CheckedValueField.DEFAULT_UNIT_FONT_SIZE));

        if (dataSetName.getFont().getSize() != fontSizeSmall) {
            dataSetName.setFont(Font.font(CheckedValueField.DEFAULT_FONT_DATASET, fontSizeSmall));
        }
        if (valueLabel.getFont().getSize() != fontSizeLarge) {
            valueLabel.setFont(Font.font(CheckedValueField.DEFAULT_FONT, fontSizeLarge));
        }
        if (unitLabel.getFont().getSize() != fontSizeSmall) {
            unitLabel.setFont(Font.font(CheckedValueField.DEFAULT_UNIT_FONT, fontSizeSmall));
        }
    };

    public void evaluateMinRangeText(final boolean applySafeDefaults) {
        try {
            setMinRange(Double.parseDouble(dataRangeMin.getText()));
        } catch (final NumberFormatException e) {
            // swallow NumberFormatException and update min range to benign min value if applicable
            if (applySafeDefaults) {
                setMinRange(Double.NEGATIVE_INFINITY);
            }
        }
    }
    public void evaluateMaxRangeText(final boolean applySafeDefaults) {
        try {
            setMaxRange(Double.parseDouble(dataRangeMax.getText()));
        } catch (final NumberFormatException e) {
            // swallow NumberFormatException and update max range to benign max value if applicable
            if (applySafeDefaults) {
                setMaxRange(Double.POSITIVE_INFINITY);
            }
        }
    }

    public CheckedValueField() {
        super();
        setMouseTransparent(true);

        dataSetName.setText("");
        dataSetName.setPrefWidth(-1);
        dataSetName.setMouseTransparent(true);
        getChildren().add(new MyHBox(dataSetName, Pos.TOP_LEFT));

        valueLabel.setText("");
        valueLabel.setFont(Font.font(CheckedValueField.DEFAULT_FONT, CheckedValueField.DEFAULT_MIN_FONT_SIZE));
        valueLabel.setPrefWidth(-1);
        valueLabel.setMouseTransparent(true);
        getChildren().add(new MyHBox(valueLabel, Pos.CENTER));

        unitLabel.setText("");
        unitLabel.setFont(Font.font(CheckedValueField.DEFAULT_UNIT_FONT, CheckedValueField.DEFAULT_MIN_FONT_SIZE));
        unitLabel.setPrefWidth(-1);
        unitLabel.setMouseTransparent(true);
        getChildren().add(new MyHBox(unitLabel, Pos.TOP_RIGHT));

        dataRangeMax.focusedProperty().addListener(minRangeFocusLost);
        dataRangeMin.setOnKeyTyped(minRangeTyped);
        minRange.addListener((ch, o, n) -> dataRangeMin.setText(n.toString()));

        dataRangeMax.focusedProperty().addListener(maxRangeFocusLost);
        dataRangeMax.setOnKeyTyped(maxRangeTyped);
        maxRange.addListener((ch, o, n) -> dataRangeMax.setText(n.toString()));

        // dynamically resize font with measurement display width TODO: reenable fixing the infinite growth bug
        // widthProperty().addListener(widthChangeListener);

        VBox.setVgrow(this, Priority.SOMETIMES);
    }
    public Label getDataSetName() {
        return dataSetName;
    }

    public double getMaxRange() {
        return maxRange.get();
    }

    public CheckedNumberTextField getMaxRangeTextField() {
        return dataRangeMax;
    }

    public double getMinRange() {
        return minRange.get();
    }

    public CheckedNumberTextField getMinRangeTextField() {
        return dataRangeMin;
    }

    public Label getUnitLabel() {
        return unitLabel;
    }
    public double getValue() {
        return value.get();
    }

    public Label getValueLabel() {
        return valueLabel;
    }

    public DoubleProperty maxRangeProperty() {
        return maxRange;
    }

    public DoubleProperty minRangeProperty() {
        return minRange;
    }

    public CheckedValueField resetRanges() {
        setMinRange(Double.NEGATIVE_INFINITY);
        setMaxRange(Double.POSITIVE_INFINITY);
        dataRangeMin.setText(Double.toString(getMinRange()));
        dataRangeMax.setText(Double.toString(getMaxRange()));
        return this;
    }

    public void setDataSetName(final String name) {
        FXUtils.runFX(() -> dataSetName.setText(name));
    }

    public CheckedValueField setMaxRange(final double value) {
        maxRange.set(Double.isNaN(value) ? Double.POSITIVE_INFINITY : value);
        dataRangeMax.setText(Double.toString(getMaxRange()));
        return this;
    }

    public CheckedValueField setMinRange(final double value) {
        minRange.set(Double.isNaN(value) ? Double.NEGATIVE_INFINITY : value);
        dataRangeMin.setText(Double.toString(getMinRange()));
        return this;
    }

    public void setUnit(final String val) {
        if (unitLabel.getText() == null || unitLabel.getText().equals(val)) {
            return;
        }
        unitLabel.setText(val);
    }

    public void setValue(final double val) {
        value.set(val);
        valueLabel.setText(Double.toString(getValue()));

        // set colour range
        setValueWarning(val < getMinRange() || val > getMaxRange());
    }

    public void setValue(final double val, final String valString) {
        if (val == getValue()) {
            return;
        }
        setValue(val);
        getValueLabel().setText(valString);
    }

    public void setValueToolTip(final String toolTip) {
        valueLabel.setTooltip(new Tooltip(toolTip));
    }

    public DoubleProperty valueProperty() {
        return value;
    }

    protected void setValueWarning(final boolean state) {
        if (state) {
            valueLabel.setTextFill(Color.RED);
            unitLabel.setTextFill(Color.RED);
        } else {
            valueLabel.setTextFill(Color.BLACK);
            unitLabel.setTextFill(Color.BLACK);
        }
    }

    private static class MyHBox extends HBox {
        public MyHBox(final Node child, final Pos position) {
            super(child);
            setAlignment(position);
            VBox.setVgrow(this, Priority.SOMETIMES);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy