From 0e2a85ae9e013bf0bebb80a82cb70cc9076e7933 Mon Sep 17 00:00:00 2001 From: serso Date: Mon, 19 Sep 2011 22:50:01 +0400 Subject: [PATCH] new widgets --- res/layout-land/number_picker.xml | 31 +++++ res/values/attrs.xml | 13 +- res/xml/preferences.xml | 28 +++-- .../DragButtonCalibrationActivity.java | 11 +- .../view/prefs/AbstractDialogPreference.java | 21 ++-- .../prefs/IntegerRangeSeekBarPreference.java | 36 ++++++ .../view/prefs/RangeSeekBarPreference.java | 117 ++++++++++++++++++ .../view/prefs/RangeSeekPreference.java | 45 ------- .../android/view/prefs/SeekBarPreference.java | 24 ++-- .../view/widgets/AbstractRangeSeekBar.java | 53 ++------ .../view/widgets/NumberRangeSeekBar.java | 61 +-------- .../android/view/widgets/NumberType.java | 68 ++++++++++ .../view/widgets/SimpleOnDragListener.java | 4 +- .../common/math/LinearNormalizer.java | 36 ++++++ 14 files changed, 361 insertions(+), 187 deletions(-) create mode 100644 res/layout-land/number_picker.xml create mode 100644 src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java create mode 100644 src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java delete mode 100644 src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java create mode 100644 src/main/java/org/solovyev/android/view/widgets/NumberType.java create mode 100644 src/main/java/org/solovyev/common/math/LinearNormalizer.java diff --git a/res/layout-land/number_picker.xml b/res/layout-land/number_picker.xml new file mode 100644 index 00000000..cad57c54 --- /dev/null +++ b/res/layout-land/number_picker.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml index fa76f4f6..5fbeb4ad 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -1,7 +1,12 @@ - - - - + + + + + + + + + diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 8f3ebff2..a09699a8 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,15 +1,27 @@ - + - + + + + \ No newline at end of file diff --git a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java index be578578..50eb77e8 100644 --- a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java +++ b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java @@ -21,6 +21,7 @@ import org.solovyev.android.view.widgets.*; import org.solovyev.common.collections.ManyValuedHashMap; import org.solovyev.common.collections.ManyValuedMap; import org.solovyev.common.utils.Interval; +import org.solovyev.common.utils.IntervalImpl; import org.solovyev.common.utils.MathUtils; import org.solovyev.common.utils.Point2d; @@ -237,7 +238,7 @@ public class DragButtonCalibrationActivity extends Activity { final float max = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MAX, defaultMax); if (min != DEFAULT_VALUE && max != DEFAULT_VALUE) { - final DragPreference directionPreference = new DragPreference(dragDirection, new Interval(min, max)); + final DragPreference directionPreference = new DragPreference(dragDirection, new IntervalImpl(min, max)); Preference preference = result.getPreferencesMap().get(preferenceType); if (preference == null) { @@ -262,10 +263,10 @@ public class DragButtonCalibrationActivity extends Activity { private DragDirection direction; @NotNull - private Interval interval; + private Interval interval; - public DragPreference(@NotNull DragDirection direction, @NotNull Interval interval) { + public DragPreference(@NotNull DragDirection direction, @NotNull Interval interval) { this.direction = direction; this.interval = interval; } @@ -280,11 +281,11 @@ public class DragButtonCalibrationActivity extends Activity { } @NotNull - public Interval getInterval() { + public Interval getInterval() { return interval; } - public void setInterval(@NotNull Interval interval) { + public void setInterval(@NotNull Interval interval) { this.interval = interval; } } diff --git a/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java b/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java index 6176da0f..ff309979 100644 --- a/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java +++ b/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java @@ -4,10 +4,10 @@ import android.content.Context; import android.preference.DialogPreference; import android.util.AttributeSet; import android.view.Gravity; -import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * User: serso @@ -20,19 +20,19 @@ public class AbstractDialogPreference extends DialogPreference { protected static final String androidns = "http://schemas.android.com/apk/res/android"; @NotNull - protected TextView splashText, valueText; + protected TextView valueTextView; @NotNull protected final Context context; - protected String dialogMessage, suffix; + @Nullable + protected String dialogMessage; public AbstractDialogPreference(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; dialogMessage = attrs.getAttributeValue(androidns, "dialogMessage"); - suffix = attrs.getAttributeValue(androidns, "text"); } @Override @@ -42,18 +42,19 @@ public class AbstractDialogPreference extends DialogPreference { layout.setOrientation(LinearLayout.VERTICAL); layout.setPadding(6, 6, 6, 6); - splashText = new TextView(context); - if (dialogMessage != null) + final TextView splashText = new TextView(context); + if (dialogMessage != null) { splashText.setText(dialogMessage); + } layout.addView(splashText); - valueText = new TextView(context); - valueText.setGravity(Gravity.CENTER_HORIZONTAL); - valueText.setTextSize(32); + valueTextView = new TextView(context); + valueTextView.setGravity(Gravity.CENTER_HORIZONTAL); + valueTextView.setTextSize(32); params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); - layout.addView(valueText, params); + layout.addView(valueTextView, params); return layout; } diff --git a/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java new file mode 100644 index 00000000..d6a17a58 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + * or visit http://se.solovyev.org + */ + +package org.solovyev.android.view.prefs; + +import android.content.Context; +import android.util.AttributeSet; +import org.jetbrains.annotations.NotNull; +import org.solovyev.common.utils.Converter; + +/** + * User: serso + * Date: 9/19/11 + * Time: 10:04 PM + */ +public class IntegerRangeSeekBarPreference extends RangeSeekBarPreference { + + public IntegerRangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) { + super(context, attrs); + } + + @NotNull + @Override + Converter getConverter() { + return new Converter() { + @NotNull + @Override + public Integer convert(@NotNull String value) { + return Integer.valueOf(value); + } + }; + } +} diff --git a/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java new file mode 100644 index 00000000..79748b74 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java @@ -0,0 +1,117 @@ +package org.solovyev.android.view.prefs; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.view.widgets.AbstractRangeSeekBar; +import org.solovyev.android.view.widgets.NumberRangeSeekBar; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.common.utils.Converter; +import org.solovyev.common.utils.StringMapper; + +import java.util.Arrays; +import java.util.List; + +/** + * User: serso + * Date: 9/19/11 + * Time: 12:27 PM + */ +public abstract class RangeSeekBarPreference extends AbstractDialogPreference implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener { + + public final static String localNameSpace = "http://schemas.android.com/apk/res/org.solovyev.android.calculator"; + + @NotNull + private AbstractRangeSeekBar rangeSeekBar; + + @NotNull + private T min; + + @NotNull + private T max; + + @NotNull + private T selectedMin; + + @NotNull + private T selectedMax; + + + public RangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) { + super(context, attrs); + + + final Converter c = getConverter(); + + String minString = attrs.getAttributeValue(localNameSpace, "min"); + min = c.convert(minString == null ? "0" : minString); + String maxString = attrs.getAttributeValue(localNameSpace, "max"); + max = c.convert(maxString == null ? "100" : maxString); + + + this.rangeSeekBar = new NumberRangeSeekBar(min, max, context); + rangeSeekBar.setOnRangeSeekBarChangeListener(this); + } + + public void setMin(@NotNull String min) { + this.min = getConverter().convert(min); + } + + public void setMax(@NotNull String max) { + this.max = getConverter().convert(max); + } + + @NotNull + abstract Converter getConverter(); + + @Override + protected LinearLayout onCreateDialogView() { + final LinearLayout result = super.onCreateDialogView(); + + this.rangeSeekBar = new NumberRangeSeekBar(min, max, context); + rangeSeekBar.setOnRangeSeekBarChangeListener(this); + initRangeSeekBar(); + + result.addView(rangeSeekBar); + + return result; + } + + @Override + protected void onBindDialogView(View v) { + super.onBindDialogView(v); + initRangeSeekBar(); + } + + private void initRangeSeekBar() { + rangeSeekBar.setSelectedMinValue(selectedMin); + rangeSeekBar.setSelectedMaxValue(selectedMax); + } + + @Override + protected void onSetInitialValue(boolean restore, Object defaultValue) { + super.onSetInitialValue(restore, defaultValue); + + final List values; + if (restore) { + values = CollectionsUtils.split(getPersistedString("0;100"), ";", new StringMapper()); + } else { + values = CollectionsUtils.split(String.valueOf(defaultValue), ";", new StringMapper()); + } + + selectedMin = getConverter().convert(values.get(0)); + selectedMax = getConverter().convert(values.get(1)); + } + + + @Override + public void rangeSeekBarValuesChanged(T minValue, T maxValue) { + final String value = CollectionsUtils.formatValue(Arrays.asList(String.valueOf(minValue), String.valueOf(maxValue)), ";", new StringMapper()); + if (shouldPersist()) { + persistString(value); + } + callChangeListener(value); + } +} diff --git a/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java b/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java deleted file mode 100644 index 8486b3ab..00000000 --- a/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.solovyev.android.view.prefs; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.view.widgets.AbstractRangeSeekBar; -import org.solovyev.android.view.widgets.NumberRangeSeekBar; - -/** - * User: serso - * Date: 9/19/11 - * Time: 12:27 PM - */ -public abstract class RangeSeekPreference extends AbstractDialogPreference implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener { - - @NotNull - private final AbstractRangeSeekBar rangeSeekBar; - - public RangeSeekPreference(@NotNull Context context, AttributeSet attrs) { - super(context, attrs); - this.rangeSeekBar = new NumberRangeSeekBar(getMinValue(), getMaxValue(), context); - rangeSeekBar.setOnRangeSeekBarChangeListener(this); - } - - @NotNull - abstract T getMinValue(); - - @NotNull - abstract T getMaxValue(); - - @Override - protected LinearLayout onCreateDialogView() { - final LinearLayout result = super.onCreateDialogView(); - - result.addView(rangeSeekBar); - - return result; - } - - @Override - public void rangeSeekBarValuesChanged(T minValue, T maxValue) { - //To change body of implemented methods use File | Settings | File Templates. - } -} diff --git a/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java index e7c4b61c..9398cd3b 100644 --- a/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java +++ b/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java @@ -6,15 +6,13 @@ package org.solovyev.android.view.prefs; -import android.preference.DialogPreference; import android.content.Context; import android.util.AttributeSet; -import android.view.Gravity; import android.view.View; import android.widget.SeekBar; -import android.widget.TextView; import android.widget.LinearLayout; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /* The following code was written by Matthew Wiggins @@ -30,17 +28,20 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB private int defaultValue, max, value = 0; + @Nullable + protected String valueText; + public SeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); defaultValue = attrs.getAttributeIntValue(androidns, "defaultValue", 0); max = attrs.getAttributeIntValue(androidns, "max", 100); - + valueText = attrs.getAttributeValue(androidns, "text"); } @Override protected LinearLayout onCreateDialogView() { - final LinearLayout layout = onCreateDialogView(); + final LinearLayout layout = super.onCreateDialogView(); seekBar = new SeekBar(context); seekBar.setOnSeekBarChangeListener(this); @@ -49,17 +50,20 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB if (shouldPersist()) value = getPersistedInt(defaultValue); - seekBar.setMax(max); - seekBar.setProgress(value); + initSeekBar(); return layout; } + private void initSeekBar() { + seekBar.setMax(max); + seekBar.setProgress(value); + } + @Override protected void onBindDialogView(View v) { super.onBindDialogView(v); - seekBar.setMax(max); - seekBar.setProgress(value); + initSeekBar(); } @Override @@ -73,7 +77,7 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) { String t = String.valueOf(value); - valueText.setText(suffix == null ? t : t.concat(suffix)); + valueTextView.setText(valueText == null ? t : t.concat(valueText)); if (shouldPersist()) persistInt(value); callChangeListener(new Integer(value)); diff --git a/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java index 29e46d1c..6afc59ef 100644 --- a/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java +++ b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java @@ -14,6 +14,7 @@ import android.widget.ImageView; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; +import org.solovyev.common.math.LinearNormalizer; import org.solovyev.common.utils.Converter; /** @@ -53,7 +54,8 @@ public abstract class AbstractRangeSeekBar extends ImageView { @NotNull private final T minValue, maxValue; - private final double dMinValue, dMaxValue; + @NotNull + private final LinearNormalizer normalizer; private double normalizedMinValue = 0d; @@ -84,8 +86,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { this.toDoubleConverter = getToDoubleConverter(); this.toTConverter = getToTConverter(); - dMinValue = toDoubleConverter.convert(minValue); - dMaxValue = toDoubleConverter.convert(maxValue); + normalizer = new LinearNormalizer(toDoubleConverter.convert(minValue), toDoubleConverter.convert(maxValue)); } @NotNull @@ -141,13 +142,8 @@ public abstract class AbstractRangeSeekBar extends ImageView { * * @param value The Number value to set the minimum value to. Will be clamped to given absolute minimum/maximum range. */ - public void setSelectedMinValue(T value) { - // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. - if (0 == (dMaxValue - dMinValue)) { - setNormalizedMinValue(0d); - } else { - setNormalizedMinValue(normalizeValue(value)); - } + public void setSelectedMinValue(@NotNull T value) { + setNormalizedMinValue(normalizeValue(value)); } /** @@ -164,13 +160,8 @@ public abstract class AbstractRangeSeekBar extends ImageView { * * @param value The Number value to set the maximum value to. Will be clamped to given absolute minimum/maximum range. */ - public void setSelectedMaxValue(T value) { - // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. - if (0 == (dMaxValue - dMinValue)) { - setNormalizedMaxValue(1d); - } else { - setNormalizedMaxValue(normalizeValue(value)); - } + public void setSelectedMaxValue(@NotNull T value) { + setNormalizedMaxValue(normalizeValue(value)); } /** @@ -330,7 +321,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { */ @SuppressWarnings("unchecked") private T denormalizeValue(double normalized) { - return toTConverter.convert(dMinValue + normalized * (dMaxValue - dMinValue)); + return toTConverter.convert(normalizer.denormalize(normalized)); } /** @@ -340,8 +331,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { * @return The normalized double. */ private double normalizeValue(T value) { - assert 0 != dMaxValue - dMinValue; - return (toDoubleConverter.convert(value) - dMinValue) / (dMaxValue - dMinValue); + return normalizer.normalize(toDoubleConverter.convert(value)); } /** @@ -390,27 +380,4 @@ public abstract class AbstractRangeSeekBar extends ImageView { MIN, MAX } - private class LinearNormalizer { - - private final double minValue; - private final double maxValue; - - private LinearNormalizer(double minValue, double maxValue) { - this.minValue = minValue; - this.maxValue = maxValue; - } - - double normalize(double value){ - if ((dMaxValue - dMinValue) != 0d) { - return (value - dMinValue) / (dMaxValue - dMinValue); - } else { - return 1d; - } - } - - double denormalize(double value){ - return dMinValue + value * (dMaxValue - dMinValue); - } - - } } diff --git a/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java index 386d5b32..0f4cf9f9 100644 --- a/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java +++ b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java @@ -2,13 +2,9 @@ package org.solovyev.android.view.widgets; import android.content.Context; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.solovyev.common.utils.Converter; -import org.solovyev.common.utils.Mapper; import org.solovyev.common.utils.NumberValuer; -import java.math.BigDecimal; - /** * User: serso * Date: 9/19/11 @@ -38,6 +34,7 @@ public class NumberRangeSeekBar extends AbstractRangeSeekBar getToTConverter() { return new Converter() { + @NotNull @Override public T convert(@NotNull Double aDouble) { return (T) numberType.toNumber(aDouble); @@ -52,60 +49,4 @@ public class NumberRangeSeekBar extends AbstractRangeSeekBar NumberType fromNumber(E value) throws IllegalArgumentException { - - for (NumberType numberType : NumberType.values()) { - if (numberType.underlyingClass.isInstance(value)) { - return numberType; - } - } - - throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported"); - } - - public T toNumber(double value) { - - switch (this) { - case LONG: - return (T)new Long((long) value); - case DOUBLE: - return (T)new Double(value); - case INTEGER: - return (T)new Integer((int) value); - case FLOAT: - return (T)new Float((float) value); - case SHORT: - return (T)new Short((short) value); - case BYTE: - return (T)new Byte((byte) value); - case BIG_DECIMAL: - return (T)new BigDecimal(value); - } - - throw new InstantiationError("can't convert " + this + " to a Number object"); - } - } } diff --git a/src/main/java/org/solovyev/android/view/widgets/NumberType.java b/src/main/java/org/solovyev/android/view/widgets/NumberType.java new file mode 100644 index 00000000..be4ead69 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/widgets/NumberType.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + * or visit http://se.solovyev.org + */ + +package org.solovyev.android.view.widgets; + +import org.jetbrains.annotations.NotNull; + +import java.math.BigDecimal; + +/** + * Utility enumeration used to convert between Numbers and doubles. + * + * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) + */ +enum NumberType { + + LONG(Long.class), + DOUBLE(Double.class), + INTEGER(Integer.class), + FLOAT(Float.class), + SHORT(Short.class), + BYTE(Byte.class), + BIG_DECIMAL(BigDecimal.class); + + @NotNull + private final Class underlyingClass; + + NumberType(@NotNull Class underlyingClass) { + this.underlyingClass = underlyingClass; + } + + @NotNull + public static NumberType fromNumber(E value) throws IllegalArgumentException { + + for (NumberType numberType : NumberType.values()) { + if (numberType.underlyingClass.isInstance(value)) { + return numberType; + } + } + + throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported"); + } + + public T toNumber(double value) { + + switch (this) { + case LONG: + return (T)new Long((long) value); + case DOUBLE: + return (T)new Double(value); + case INTEGER: + return (T)new Integer((int) value); + case FLOAT: + return (T)new Float((float) value); + case SHORT: + return (T)new Short((short) value); + case BYTE: + return (T)new Byte((byte) value); + case BIG_DECIMAL: + return (T)new BigDecimal(value); + } + + throw new InstantiationError("can't convert " + this + " to a Number object"); + } +} diff --git a/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java b/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java index 4f12f3a8..13a7b109 100644 --- a/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java +++ b/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java @@ -85,8 +85,8 @@ public class SimpleOnDragListener implements OnDragListener, DragPreferencesChan return result; } - private boolean isInInterval(@NotNull Interval interval, float value) { - return interval.getStart() - MathUtils.MIN_AMOUNT <= value && value <= interval.getEnd() + MathUtils.MIN_AMOUNT; + private boolean isInInterval(@NotNull Interval interval, float value) { + return interval.getLeftBorder() - MathUtils.MIN_AMOUNT <= value && value <= interval.getRightBorder() + MathUtils.MIN_AMOUNT; } @Override diff --git a/src/main/java/org/solovyev/common/math/LinearNormalizer.java b/src/main/java/org/solovyev/common/math/LinearNormalizer.java new file mode 100644 index 00000000..c0b3a3af --- /dev/null +++ b/src/main/java/org/solovyev/common/math/LinearNormalizer.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + * or visit http://se.solovyev.org + */ + +package org.solovyev.common.math; + +/** +* User: serso +* Date: 9/19/11 +* Time: 9:31 PM +*/ +public class LinearNormalizer { + + private final double min; + private final double max; + + public LinearNormalizer(double min, double max) { + this.min = min; + this.max = max; + } + + public double normalize(double value){ + if ((max - min) != 0d) { + return (value - min) / (max - min); + } else { + return 1d; + } + } + + public double denormalize(double value){ + return min + value * (max - min); + } + +}