diff options
24 files changed, 419 insertions, 32 deletions
diff --git a/CHANGELOG.org b/CHANGELOG.org new file mode 100644 index 0000000..1dbe268 --- /dev/null +++ b/CHANGELOG.org @@ -0,0 +1,11 @@ +* Changelog +All notable changes in this project will be shown in this file. + +** v0.1.0 +NOTE: At this stage, the API is subject to significant change. +*** Added + - Unit interface, implemented and supporting classes + - UnitPrefix interface, implemented and supporting classes + - UnitDimension and supporting classes + - UnitDatabase to store and parse units + - A GUI for unit conversion diff --git a/README.org b/README.org new file mode 100644 index 0000000..175db07 --- /dev/null +++ b/README.org @@ -0,0 +1,62 @@ +* What is it? + This is a unit converter, which allows you to convert between different units, and includes a GUI which can read unit data from a file (using some unit math) and convert between units that you type in, and has a unit and prefix viewer to check the units that have been loaded in. +* Features + - Convert between units and expressions of units + - linear or base unit can use unit prefixes (including non-metric units!) + - and prefixes are defined in an editable data file, in a simple and intuitive format. + - Viewer and Prefix Viewer which allow you to search through all of the available units and prefixes and learn details about them. + - All of SI included in default text file + - Choose your precision +* How to Convert +To convert units, simply enter the first unit in the From box and the second unit in the To box. Press Convert and a result will appear in the output box. Both boxes accept unit expressions, so you can input things like ‘1.7 m’, ‘85 km/h’ and ‘35 A * 14 s’ into either box. + +*Warning*: The space between the number and the unit name is required, or else the whole expression will be interpreted as a unit name. Spaces are not required for operators. + +Use the slider at the bottom to choose the maximum precision of the result, in significant digits, not decimal places. +* Units Files and Expressions +As mentioned previously, all units are loaded from a units file. The format for lines consists of a name for the unit, some tabs (not spaces), and an expression. The following operations are supported in expressions: + - Multiplication using spaces ( ) or asterisks (*) + - Division using the forward slash (/) + - Exponentiation using the caret (^) +Every argument can be either a linear unit, a base unit or a number, except exponents which must be integers. There is no way to use brackets to manipulate order of operations. + +Example (Explanation provided after # sign, this will *not* work in a real units file): + +inch 25.4 mm # Define ‘inch’ as equal to the product of 25.4 and ‘mm’ + +mph mile / hour # Define ‘mph’ as equal to the quotient of ‘mile’ and ‘hour’ + +litre 0.001 m^3 # Define ‘litre’ as equal to the product of 0.001 and the unit ‘m’ raised to the exponent 3 + +Lines that start with the number sign (#) and blank lines will be ignored. + +Unit prefixes are defined differently. When a unit name ends with the dash (-) character, it is interpreted as a prefix. Prefix expressions are not as powerful as unit expressions, they can only be: + - a number (1000) + - an exponent (10^3) + - the name of another prefix without the dash (kilo) +* Unit Prefixes +In SI, you can have a unit prefix, which you attach to the start of a unit and it multiplies the unit by a certain value. For example, milli-metre = 0.001 * metre. This unit converter supports unit prefixes, and you can put any number of prefixes before a linear or base unit to transform it (this includes non-SI units). +You can use more than one prefix at once (yottayottametre = really really long distance), but you may not convert prefixes alone. If you want to do that, use ‘unit’ or ‘u’ (ku = 1000000 mu). You can also use u for converting from numbers (pi = 3.141593 u). + +*Warning*: While the standard symbol for ‘deca’ is ‘da’, this program uses ‘D’ instead since ‘da’ can be confused with ‘deciatto’. Also, you may use capital letters for the symbols of ‘hecto’ and ‘kilo’. + +*Warning*: The standard prefixes will never use 1024 instead of 1000, even when operating on bits and bytes. Use ‘Ki’, ‘Mi’, ‘Gi’, ‘Ti’ and so on instead. +* Nonlinear Units +Sometimes, units cannot be converted from and to by simply multiplying and dividing. A common example of this is the Celsius and Fahrenheit temperature scales, which require multiplication and addition to convert to each other (and to their base, Kelvin). + +To use nonlinear units, use the following syntax: +FROM: unit1(value) +TO: unit2 + +Nonlinear units cannot: + - multiply, divide or exponentiate + - use prefixes + - be defined by unit files + +To define a nonlinear unit, make an anonymous inner type (or any other subclass) of AbstractUnit, and define the conversion methods. +* Unit and Prefix Viewers +The unit and prefix viewers can be used to see the available units (without prefixes) and prefixes. Upon opening them, you will see a list of units or prefixes on your left. Using the text box above, the list can be filtered. When a unit is clicked on, details about will be displayed on the right. +* Copyright and Licences +The Unit Converter program is Copyright (C) 2018, 2019 Adrien Hopkins. It is released under the terms of the AGPL v3 licence. + +This document is Copyright (C) 2019 Adrien Hopkins. It is released under the terms of the CC BY-SA (Creative Commons Attribution-ShareAlike) licence. diff --git a/src/unitConverter/UnitsDatabase.java b/src/unitConverter/UnitsDatabase.java index d479917..4816db1 100755 --- a/src/unitConverter/UnitsDatabase.java +++ b/src/unitConverter/UnitsDatabase.java @@ -41,12 +41,14 @@ import unitConverter.unit.UnitPrefix; * * @author Adrien Hopkins * @since 2019-01-07 + * @since v0.1.0 */ public final class UnitsDatabase { /** * The units in this system. * * @since 2019-01-07 + * @since v0.1.0 */ private final Map<String, Unit> units; @@ -54,6 +56,7 @@ public final class UnitsDatabase { * The unit prefixes in this system. * * @since 2019-01-14 + * @since v0.1.0 */ private final Map<String, UnitPrefix> prefixes; @@ -61,6 +64,7 @@ public final class UnitsDatabase { * Creates the {@code UnitsDatabase}. * * @since 2019-01-10 + * @since v0.1.0 */ public UnitsDatabase() { this.units = new HashMap<>(); @@ -90,6 +94,7 @@ public final class UnitsDatabase { * @throws NullPointerException * if file is null * @since 2019-01-13 + * @since v0.1.0 */ public void addAllFromFile(final File file) { Objects.requireNonNull(file, "file must not be null."); @@ -128,7 +133,7 @@ public final class UnitsDatabase { if (name.endsWith("-")) { final UnitPrefix prefix; try { - prefix = this.getPrefixFromExpression(expression, name.substring(0, name.length() - 1)); + prefix = this.getPrefixFromExpression(expression); } catch (final IllegalArgumentException e) { System.err.printf("Parsing error on line %d:%n", lineCounter); throw e; @@ -168,6 +173,7 @@ public final class UnitsDatabase { * @throws NullPointerException * if name or unit is null * @since 2019-01-14 + * @since v0.1.0 */ public void addPrefix(final String name, final UnitPrefix prefix) { this.prefixes.put(Objects.requireNonNull(name, "name must not be null."), @@ -184,6 +190,7 @@ public final class UnitsDatabase { * @throws NullPointerException * if unit is null * @since 2019-01-10 + * @since v0.1.0 */ public void addUnit(final String name, final Unit unit) { this.units.put(name, Objects.requireNonNull(unit, "unit must not be null.")); @@ -196,6 +203,7 @@ public final class UnitsDatabase { * name to test * @return if database contains name * @since 2019-01-13 + * @since v0.1.0 */ public boolean containsPrefixlessUnitName(final String name) { return this.units.containsKey(name); @@ -208,6 +216,7 @@ public final class UnitsDatabase { * name to test * @return if database contains name * @since 2019-01-13 + * @since v0.1.0 */ public boolean containsPrefixName(final String name) { return this.prefixes.containsKey(name); @@ -220,6 +229,7 @@ public final class UnitsDatabase { * name to test * @return if database contains name * @since 2019-01-13 + * @since v0.1.0 */ public boolean containsUnitName(final String name) { // check for prefixes @@ -238,13 +248,14 @@ public final class UnitsDatabase { * prefix's name * @return prefix * @since 2019-01-10 + * @since v0.1.0 */ public UnitPrefix getPrefix(final String name) { return this.prefixes.get(name); } /** - * Gets a unit prefix from a prefix expression and a name + * Gets a unit prefix from a prefix expression * <p> * Currently, prefix expressions are much simpler than unit expressions: They are either a number or the name of * another prefix @@ -252,18 +263,16 @@ public final class UnitsDatabase { * * @param expression * expression to input - * @param name - * name of prefix if a new prefix is created * @return prefix * @throws IllegalArgumentException * if expression cannot be parsed * @throws NullPointerException * if any argument is null * @since 2019-01-14 + * @since v0.1.0 */ - public UnitPrefix getPrefixFromExpression(final String expression, final String name) { + public UnitPrefix getPrefixFromExpression(final String expression) { Objects.requireNonNull(expression, "expression must not be null."); - Objects.requireNonNull(name, "name must not be null."); try { return new DefaultUnitPrefix(Double.parseDouble(expression)); @@ -301,6 +310,7 @@ public final class UnitsDatabase { * unit's name * @return unit * @since 2019-01-10 + * @since v0.1.0 */ public Unit getPrefixlessUnit(final String name) { return this.units.get(name); @@ -313,6 +323,7 @@ public final class UnitsDatabase { * unit's name * @return unit * @since 2019-01-10 + * @since v0.1.0 */ public Unit getUnit(final String name) { if (name.contains("^")) { @@ -377,21 +388,19 @@ public final class UnitsDatabase { * <li>The name of a unit, which multiplies or divides the result based on preceding operators</li> * <li>The operators '*' and '/', which multiply and divide (note that just putting two units or values next to each * other is equivalent to multiplication)</li> + * <li>The operator '^' which exponentiates. Exponents must be integers.</li> * <li>A number which is multiplied or divided</li> * </ul> * This method only works with linear units. - * <p> - * If the expression contains just the name of a unit, returns that unit without changing name or symbol. This - * exists for the creation of aliases. - * </p> * - * @param line - * line to parse + * @param expression + * expression to parse * @throws IllegalArgumentException * if the expression cannot be parsed * @throws NullPointerException * if any argument is null * @since 2019-01-07 + * @since v0.1.0 */ public Unit getUnitFromExpression(final String expression) { Objects.requireNonNull(expression, "expression must not be null."); @@ -558,6 +567,7 @@ public final class UnitsDatabase { /** * @return an immutable set of all of the unit names in this database, ignoring prefixes * @since 2019-01-14 + * @since v0.1.0 */ public Set<String> prefixlessUnitNameSet() { return Collections.unmodifiableSet(this.units.keySet()); @@ -566,6 +576,7 @@ public final class UnitsDatabase { /** * @return an immutable set of all of the prefix names in this database * @since 2019-01-14 + * @since v0.1.0 */ public Set<String> prefixNameSet() { return Collections.unmodifiableSet(this.prefixes.keySet()); diff --git a/src/unitConverter/converterGUI/DelegateListModel.java b/src/unitConverter/converterGUI/DelegateListModel.java index 42bc0dc..0e9b342 100755 --- a/src/unitConverter/converterGUI/DelegateListModel.java +++ b/src/unitConverter/converterGUI/DelegateListModel.java @@ -32,10 +32,12 @@ import javax.swing.AbstractListModel; * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ final class DelegateListModel<E> extends AbstractListModel<E> implements List<E> { /** * @since 2019-01-14 + * @since v0.1.0 */ private static final long serialVersionUID = 8985494428224810045L; @@ -43,6 +45,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> implements List<E> * The list that this model is a delegate to. * * @since 2019-01-14 + * @since v0.1.0 */ private final List<E> delegate; @@ -52,6 +55,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> implements List<E> * @param delegate * list to delegate * @since 2019-01-14 + * @since v0.1.0 */ public DelegateListModel(final List<E> delegate) { this.delegate = delegate; diff --git a/src/unitConverter/converterGUI/FilterComparator.java b/src/unitConverter/converterGUI/FilterComparator.java index ab25f2f..27ec3ab 100755 --- a/src/unitConverter/converterGUI/FilterComparator.java +++ b/src/unitConverter/converterGUI/FilterComparator.java @@ -17,14 +17,29 @@ package unitConverter.converterGUI;
import java.util.Comparator;
+import java.util.Objects;
/**
+ * A comparator that compares strings using a filter.
+ *
* @author Adrien Hopkins
* @since 2019-01-15
+ * @since v0.1.0
*/
public final class FilterComparator implements Comparator<String> {
-
+ /**
+ * The filter that the comparator is filtered by.
+ *
+ * @since 2019-01-15
+ * @since v0.1.0
+ */
private final String filter;
+ /**
+ * The comparator to use if the arguments are otherwise equal.
+ *
+ * @since 2019-01-15
+ * @since v0.1.0
+ */
private final Comparator<String> comparator;
/**
@@ -32,6 +47,7 @@ public final class FilterComparator implements Comparator<String> { *
* @param filter
* @since 2019-01-15
+ * @since v0.1.0
*/
public FilterComparator(final String filter) {
this(filter, null);
@@ -41,11 +57,16 @@ public final class FilterComparator implements Comparator<String> { * Creates the {@code FilterComparator}.
*
* @param filter
+ * string to filter by
* @param comparator
+ * comparator to fall back to if all else fails, null is compareTo.
* @since 2019-01-15
+ * @since v0.1.0
+ * @throws NullPointerException
+ * if filter is null
*/
public FilterComparator(final String filter, final Comparator<String> comparator) {
- this.filter = filter;
+ this.filter = Objects.requireNonNull(filter, "filter must not be null.");
this.comparator = comparator;
}
diff --git a/src/unitConverter/converterGUI/GridBagBuilder.java b/src/unitConverter/converterGUI/GridBagBuilder.java index 7a0615a..e036677 100755 --- a/src/unitConverter/converterGUI/GridBagBuilder.java +++ b/src/unitConverter/converterGUI/GridBagBuilder.java @@ -20,11 +20,16 @@ import java.awt.GridBagConstraints; import java.awt.Insets; /** + * A builder for Java's {@link java.awt.GridBagConstraints} class. + * * @author Adrien Hopkins * @since 2018-11-30 + * @since v0.1.0 */ final class GridBagBuilder { /** + * The built {@code GridBagConstraints}'s {@code gridx} property. + * <p> * Specifies the cell containing the leading edge of the component's display area, where the first cell in a row has * <code>gridx=0</code>. The leading edge of a component's display area is its left edge for a horizontal, * left-to-right container and its right edge for a horizontal, right-to-left container. The value @@ -41,6 +46,8 @@ final class GridBagBuilder { private final int gridx; /** + * The built {@code GridBagConstraints}'s {@code gridy} property. + * <p> * Specifies the cell at the top of the component's display area, where the topmost cell has <code>gridy=0</code>. * The value <code>RELATIVE</code> specifies that the component be placed just below the component that was added to * the container just before this component was added. @@ -54,6 +61,8 @@ final class GridBagBuilder { private final int gridy; /** + * The built {@code GridBagConstraints}'s {@code gridwidth} property. + * <p> * Specifies the number of cells in a row for the component's display area. * <p> * Use <code>REMAINDER</code> to specify that the component's display area will be from <code>gridx</code> to the @@ -69,6 +78,8 @@ final class GridBagBuilder { private final int gridwidth; /** + * The built {@code GridBagConstraints}'s {@code gridheight} property. + * <p> * Specifies the number of cells in a column for the component's display area. * <p> * Use <code>REMAINDER</code> to specify that the component's display area will be from <code>gridy</code> to the @@ -84,6 +95,8 @@ final class GridBagBuilder { private final int gridheight; /** + * The built {@code GridBagConstraints}'s {@code weightx} property. + * <p> * Specifies how to distribute extra horizontal space. * <p> * The grid bag layout manager calculates the weight of a column to be the maximum <code>weightx</code> of all the @@ -103,6 +116,8 @@ final class GridBagBuilder { private double weightx; /** + * The built {@code GridBagConstraints}'s {@code weighty} property. + * <p> * Specifies how to distribute extra vertical space. * <p> * The grid bag layout manager calculates the weight of a row to be the maximum <code>weighty</code> of all the @@ -122,6 +137,8 @@ final class GridBagBuilder { private double weighty; /** + * The built {@code GridBagConstraints}'s {@code anchor} property. + * <p> * This field is used when the component is smaller than its display area. It determines where, within the display * area, to place the component. * <p> @@ -145,6 +162,8 @@ final class GridBagBuilder { private int anchor; /** + * The built {@code GridBagConstraints}'s {@code fill} property. + * <p> * This field is used when the component's display area is larger than the component's requested size. It determines * whether to resize the component, and if so, how. * <p> @@ -167,6 +186,8 @@ final class GridBagBuilder { private int fill; /** + * The built {@code GridBagConstraints}'s {@code insets} property. + * <p> * This field specifies the external padding of the component, the minimum amount of space between the component and * the edges of its display area. * <p> @@ -178,6 +199,8 @@ final class GridBagBuilder { private Insets insets; /** + * The built {@code GridBagConstraints}'s {@code ipadx} property. + * <p> * This field specifies the internal padding of the component, how much space to add to the minimum width of the * component. The width of the component is at least its minimum width plus <code>ipadx</code> pixels. * <p> @@ -190,6 +213,8 @@ final class GridBagBuilder { private int ipadx; /** + * The built {@code GridBagConstraints}'s {@code ipady} property. + * <p> * This field specifies the internal padding, that is, how much space to add to the minimum height of the component. * The height of the component is at least its minimum height plus <code>ipady</code> pixels. * <p> @@ -207,6 +232,7 @@ final class GridBagBuilder { * @param gridy * y position * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder(final int gridx, final int gridy) { this(gridx, gridy, 1, 1); @@ -222,6 +248,7 @@ final class GridBagBuilder { * @param gridheight * number of cells occupied vertically * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder(final int gridx, final int gridy, final int gridwidth, final int gridheight) { this(gridx, gridy, gridwidth, gridheight, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, @@ -245,6 +272,7 @@ final class GridBagBuilder { * @param ipadx * @param ipady * @since 2018-11-30 + * @since v0.1.0 */ private GridBagBuilder(final int gridx, final int gridy, final int gridwidth, final int gridheight, final double weightx, final double weighty, final int anchor, final int fill, final Insets insets, @@ -266,6 +294,7 @@ final class GridBagBuilder { /** * @return {@code GridBagConstraints} created by this builder * @since 2018-11-30 + * @since v0.1.0 */ public GridBagConstraints build() { return new GridBagConstraints(this.gridx, this.gridy, this.gridwidth, this.gridheight, this.weightx, @@ -275,6 +304,7 @@ final class GridBagBuilder { /** * @return anchor * @since 2018-11-30 + * @since v0.1.0 */ public int getAnchor() { return this.anchor; @@ -283,6 +313,7 @@ final class GridBagBuilder { /** * @return fill * @since 2018-11-30 + * @since v0.1.0 */ public int getFill() { return this.fill; @@ -291,6 +322,7 @@ final class GridBagBuilder { /** * @return gridheight * @since 2018-11-30 + * @since v0.1.0 */ public int getGridheight() { return this.gridheight; @@ -299,6 +331,7 @@ final class GridBagBuilder { /** * @return gridwidth * @since 2018-11-30 + * @since v0.1.0 */ public int getGridwidth() { return this.gridwidth; @@ -307,6 +340,7 @@ final class GridBagBuilder { /** * @return gridx * @since 2018-11-30 + * @since v0.1.0 */ public int getGridx() { return this.gridx; @@ -315,6 +349,7 @@ final class GridBagBuilder { /** * @return gridy * @since 2018-11-30 + * @since v0.1.0 */ public int getGridy() { return this.gridy; @@ -323,6 +358,7 @@ final class GridBagBuilder { /** * @return insets * @since 2018-11-30 + * @since v0.1.0 */ public Insets getInsets() { return this.insets; @@ -331,6 +367,7 @@ final class GridBagBuilder { /** * @return ipadx * @since 2018-11-30 + * @since v0.1.0 */ public int getIpadx() { return this.ipadx; @@ -339,6 +376,7 @@ final class GridBagBuilder { /** * @return ipady * @since 2018-11-30 + * @since v0.1.0 */ public int getIpady() { return this.ipady; @@ -347,6 +385,7 @@ final class GridBagBuilder { /** * @return weightx * @since 2018-11-30 + * @since v0.1.0 */ public double getWeightx() { return this.weightx; @@ -355,6 +394,7 @@ final class GridBagBuilder { /** * @return weighty * @since 2018-11-30 + * @since v0.1.0 */ public double getWeighty() { return this.weighty; @@ -364,6 +404,7 @@ final class GridBagBuilder { * @param anchor * anchor to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setAnchor(final int anchor) { this.anchor = anchor; @@ -374,6 +415,7 @@ final class GridBagBuilder { * @param fill * fill to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setFill(final int fill) { this.fill = fill; @@ -384,6 +426,7 @@ final class GridBagBuilder { * @param insets * insets to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setInsets(final Insets insets) { this.insets = insets; @@ -394,6 +437,7 @@ final class GridBagBuilder { * @param ipadx * ipadx to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setIpadx(final int ipadx) { this.ipadx = ipadx; @@ -404,6 +448,7 @@ final class GridBagBuilder { * @param ipady * ipady to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setIpady(final int ipady) { this.ipady = ipady; @@ -414,6 +459,7 @@ final class GridBagBuilder { * @param weightx * weightx to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setWeightx(final double weightx) { this.weightx = weightx; @@ -424,6 +470,7 @@ final class GridBagBuilder { * @param weighty * weighty to set * @since 2018-11-30 + * @since v0.1.0 */ public GridBagBuilder setWeighty(final double weighty) { this.weighty = weighty; diff --git a/src/unitConverter/converterGUI/UnitConverterGUI.java b/src/unitConverter/converterGUI/UnitConverterGUI.java index 0068312..b54e0da 100755 --- a/src/unitConverter/converterGUI/UnitConverterGUI.java +++ b/src/unitConverter/converterGUI/UnitConverterGUI.java @@ -52,6 +52,7 @@ import unitConverter.unit.UnitPrefix; /** * @author Adrien Hopkins * @since 2018-12-27 + * @since v0.1.0 */ final class UnitConverterGUI { private static class Presenter { @@ -83,6 +84,7 @@ final class UnitConverterGUI { * @param view * presenter's associated view * @since 2018-12-27 + * @since v0.1.0 */ Presenter(final View view) { this.view = view; @@ -141,6 +143,17 @@ final class UnitConverterGUI { AbstractUnit.getBaseUnitCount()); } + /** + * Runs whenever the convert button is pressed. + * + * <p> + * Reads and parses a unit expression from the from and to boxes, then converts {@code from} to {@code to}. Any + * errors are shown in JOptionPanes. + * </p> + * + * @since 2019-01-26 + * @since v0.1.0 + */ public final void convert() { final String fromUnitString = this.view.getFromText(); final String toUnitString = this.view.getToText(); @@ -196,6 +209,7 @@ final class UnitConverterGUI { * @param filter * filter to use * @since 2019-01-15 + * @since v0.1.0 */ private final void filterFilteredPrefixModel(final Predicate<String> filter) { this.prefixNamesFiltered.clear(); @@ -212,6 +226,7 @@ final class UnitConverterGUI { * @param filter * filter to use * @since 2019-01-15 + * @since v0.1.0 */ private final void filterFilteredUnitModel(final Predicate<String> filter) { this.unitNamesFiltered.clear(); @@ -225,11 +240,21 @@ final class UnitConverterGUI { /** * @return a list model of all of the unit keys * @since 2019-01-14 + * @since v0.1.0 */ public final ListModel<String> keyListModel() { return this.unitNamesFiltered; } + /** + * Runs whenever the prefix filter is changed. + * <p> + * Filters the prefix list then sorts it using a {@code FilterComparator}. + * </p> + * + * @since 2019-01-15 + * @since v0.1.0 + */ public final void prefixFilterUpdated() { final String filter = this.view.getPrefixFilterText(); if (filter.equals("")) { @@ -241,13 +266,22 @@ final class UnitConverterGUI { } /** - * @return a list model of all fo the prefix names + * @return a list model of all of the prefix names * @since 2019-01-15 */ public final ListModel<String> prefixNameListModel() { return this.prefixNamesFiltered; } + /** + * Runs whenever a prefix is selected in the viewer. + * <p> + * Shows its information in the text box to the right. + * </p> + * + * @since 2019-01-15 + * @since v0.1.0 + */ public final void prefixSelected() { final int index = this.view.getPrefixListSelection(); if (index == -1) @@ -269,6 +303,15 @@ final class UnitConverterGUI { this.significantFigures = significantFigures; } + /** + * Runs whenever the unit filter is changed. + * <p> + * Filters the unit list then sorts it using a {@code FilterComparator}. + * </p> + * + * @since 2019-01-15 + * @since v0.1.0 + */ public final void unitFilterUpdated() { final String filter = this.view.getUnitFilterText(); if (filter.equals("")) { @@ -280,8 +323,13 @@ final class UnitConverterGUI { } /** + * Runs whenever a unit is selected in the viewer. + * <p> + * Shows its information in the text box to the right. + * </p> * * @since 2019-01-15 + * @since v0.1.0 */ public void unitNameSelected() { final int index = this.view.getUnitListSelection(); @@ -302,26 +350,37 @@ final class UnitConverterGUI { /** The view's associated presenter. */ private final Presenter presenter; + /** The list of unit names in the unit viewer */ private final JList<String> unitNameList; + /** The list of prefix names in the prefix viewer */ private final JList<String> prefixNameList; + /** The unit search box in the unit viewer */ private final JTextField unitFilterEntry; + /** The text box for unit data in the unit viewer */ private final JTextArea unitTextBox; + /** The prefix search box in the prefix viewer */ private final JTextField prefixFilterEntry; + /** The text box for prefix data in the prefix viewer */ private final JTextArea prefixTextBox; + /** The "From" entry in the conversion panel */ private final JTextField fromEntry; + /** The "To" entry in the conversion panel */ private final JTextField toEntry; + /** The output area in the conversion panel */ private final JTextArea output; /** * Creates the {@code View}. * * @since 2019-01-14 + * @since v0.1.0 */ public View() { this.presenter = new Presenter(this); this.frame = new JFrame("Unit Converter"); this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // create the components this.unitNameList = new JList<>(this.presenter.keyListModel()); this.prefixNameList = new JList<>(this.presenter.prefixNameListModel()); this.unitFilterEntry = new JTextField(); @@ -332,11 +391,17 @@ final class UnitConverterGUI { this.toEntry = new JTextField(); this.output = new JTextArea(2, 32); + // create more components this.initComponents(); this.frame.pack(); } + /** + * @return text in "From" box in converter panel + * @since 2019-01-15 + * @since v0.1.0 + */ public String getFromText() { return this.fromEntry.getText(); } @@ -344,6 +409,7 @@ final class UnitConverterGUI { /** * @return text in prefix filter * @since 2019-01-15 + * @since v0.1.0 */ public String getPrefixFilterText() { return this.prefixFilterEntry.getText(); @@ -352,11 +418,17 @@ final class UnitConverterGUI { /** * @return index of selected prefix * @since 2019-01-15 + * @since v0.1.0 */ public int getPrefixListSelection() { return this.prefixNameList.getSelectedIndex(); } + /** + * @return text in "To" box in converter panel + * @since 2019-01-26 + * @since v0.1.0 + */ public String getToText() { return this.toEntry.getText(); } @@ -372,6 +444,7 @@ final class UnitConverterGUI { /** * @return index of selected unit * @since 2019-01-15 + * @since v0.1.0 */ public int getUnitListSelection() { return this.unitNameList.getSelectedIndex(); @@ -381,6 +454,7 @@ final class UnitConverterGUI { * Starts up the application. * * @since 2018-12-27 + * @since v0.1.0 */ public final void init() { this.frame.setVisible(true); @@ -390,6 +464,7 @@ final class UnitConverterGUI { * Initializes the view's components. * * @since 2018-12-27 + * @since v0.1.0 */ private final void initComponents() { final JPanel masterPanel = new JPanel(); @@ -451,7 +526,7 @@ final class UnitConverterGUI { } } - { + { // panel for specifying precision final JPanel sigDigPanel = new JPanel(); convertPanel.add(sigDigPanel); @@ -485,7 +560,7 @@ final class UnitConverterGUI { listPanel.setLayout(new BorderLayout()); - { + { // unit search box listPanel.add(this.unitFilterEntry, BorderLayout.PAGE_START); this.unitFilterEntry.addCaretListener(e -> this.presenter.unitFilterUpdated()); } @@ -512,13 +587,13 @@ final class UnitConverterGUI { prefixLookupPanel.setLayout(new GridLayout(1, 2)); - { + { // panel for listing and seaching final JPanel prefixListPanel = new JPanel(); prefixLookupPanel.add(prefixListPanel); prefixListPanel.setLayout(new BorderLayout()); - { + { // prefix search box prefixListPanel.add(this.prefixFilterEntry, BorderLayout.PAGE_START); this.prefixFilterEntry.addCaretListener(e -> this.presenter.prefixFilterUpdated()); } @@ -540,6 +615,14 @@ final class UnitConverterGUI { } } + /** + * Sets the text in the output of the conversion panel. + * + * @param text + * text to set + * @since 2019-01-15 + * @since v0.1.0 + */ public void setOutputText(final String text) { this.output.setText(text); } @@ -550,6 +633,7 @@ final class UnitConverterGUI { * @param text * text to set * @since 2019-01-15 + * @since v0.1.0 */ public void setPrefixTextBoxText(final String text) { this.prefixTextBox.setText(text); @@ -574,6 +658,7 @@ final class UnitConverterGUI { * @param message * message in dialog * @since 2019-01-14 + * @since v0.1.0 */ public void showErrorDialog(final String title, final String message) { JOptionPane.showMessageDialog(this.frame, message, title, JOptionPane.ERROR_MESSAGE); diff --git a/src/unitConverter/dimension/BaseDimension.java b/src/unitConverter/dimension/BaseDimension.java index 6a727a9..0c09dce 100755 --- a/src/unitConverter/dimension/BaseDimension.java +++ b/src/unitConverter/dimension/BaseDimension.java @@ -21,17 +21,20 @@ package unitConverter.dimension; * * @author Adrien Hopkins * @since 2018-12-22 + * @since v0.1.0 */ public interface BaseDimension { /** * @return the dimension's name - * @since 2019-01-25 + * @since 2018-12-22 + * @since v0.1.0 */ String getName(); /** * @return a short string (usually one character) that represents this base dimension * @since 2018-12-22 + * @since v0.1.0 */ String getSymbol(); } diff --git a/src/unitConverter/dimension/OtherBaseDimension.java b/src/unitConverter/dimension/OtherBaseDimension.java index 2ab19b3..8c6d25d 100755 --- a/src/unitConverter/dimension/OtherBaseDimension.java +++ b/src/unitConverter/dimension/OtherBaseDimension.java @@ -23,6 +23,7 @@ import java.util.Objects; * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ public enum OtherBaseDimension implements BaseDimension { INFORMATION("Info"), CURRENCY("$$"); @@ -36,6 +37,7 @@ public enum OtherBaseDimension implements BaseDimension { * @param symbol * dimension's symbol * @since 2018-12-11 + * @since v0.1.0 */ private OtherBaseDimension(final String symbol) { this.symbol = Objects.requireNonNull(symbol, "symbol must not be null."); diff --git a/src/unitConverter/dimension/SIBaseDimension.java b/src/unitConverter/dimension/SIBaseDimension.java index b731b00..928d8d6 100755 --- a/src/unitConverter/dimension/SIBaseDimension.java +++ b/src/unitConverter/dimension/SIBaseDimension.java @@ -23,6 +23,7 @@ import java.util.Objects; *
* @author Adrien Hopkins
* @since 2018-12-11
+ * @since v0.1.0
*/
public enum SIBaseDimension implements BaseDimension {
LENGTH("L"), MASS("M"), TIME("T"), ELECTRIC_CURRENT("I"), TEMPERATURE("\u0398"), // u0398 is the theta symbol
@@ -37,6 +38,7 @@ public enum SIBaseDimension implements BaseDimension { * @param symbol
* dimension's symbol
* @since 2018-12-11
+ * @since v0.1.0
*/
private SIBaseDimension(final String symbol) {
this.symbol = Objects.requireNonNull(symbol, "symbol must not be null.");
diff --git a/src/unitConverter/dimension/StandardDimensions.java b/src/unitConverter/dimension/StandardDimensions.java index c830f00..b3edb7d 100755 --- a/src/unitConverter/dimension/StandardDimensions.java +++ b/src/unitConverter/dimension/StandardDimensions.java @@ -21,6 +21,7 @@ package unitConverter.dimension; *
* @author Adrien Hopkins
* @since 2018-12-11
+ * @since v0.1.0
*/
public final class StandardDimensions {
// base dimensions
diff --git a/src/unitConverter/dimension/UnitDimension.java b/src/unitConverter/dimension/UnitDimension.java index ba2a750..40e5bbc 100755 --- a/src/unitConverter/dimension/UnitDimension.java +++ b/src/unitConverter/dimension/UnitDimension.java @@ -29,12 +29,14 @@ import java.util.Set; *
* @author Adrien Hopkins
* @since 2018-12-11
+ * @since v0.1.0
*/
public final class UnitDimension {
/**
* The unit dimension where every exponent is zero
*
* @since 2018-12-12
+ * @since v0.1.0
*/
public static final UnitDimension EMPTY = new UnitDimension(new HashMap<>());
@@ -45,6 +47,7 @@ public final class UnitDimension { * dimension to get
* @return unit dimension
* @since 2018-12-11
+ * @since v0.1.0
*/
public static final UnitDimension getBase(final BaseDimension dimension) {
final Map<BaseDimension, Integer> map = new HashMap<>();
@@ -56,6 +59,7 @@ public final class UnitDimension { * The base dimensions that make up this dimension.
*
* @since 2018-12-11
+ * @since v0.1.0
*/
final Map<BaseDimension, Integer> exponents;
@@ -65,6 +69,7 @@ public final class UnitDimension { * @param exponents
* base dimensions that make up this dimension
* @since 2018-12-11
+ * @since v0.1.0
*/
private UnitDimension(final Map<BaseDimension, Integer> exponents) {
this.exponents = new HashMap<>(exponents);
@@ -77,6 +82,7 @@ public final class UnitDimension { * other dimension
* @return quotient of two dimensions
* @since 2018-12-11
+ * @since v0.1.0
*/
public UnitDimension dividedBy(final UnitDimension other) {
final Map<BaseDimension, Integer> map = new HashMap<>(this.exponents);
@@ -119,6 +125,7 @@ public final class UnitDimension { /**
* @return a set of all of the base dimensions with non-zero exponents that make up this dimension.
* @since 2018-12-12
+ * @since v0.1.0
*/
public final Set<BaseDimension> getBaseSet() {
final Set<BaseDimension> dimensions = new HashSet<>();
@@ -140,6 +147,7 @@ public final class UnitDimension { * dimension to check
* @return exponent for that dimension
* @since 2018-12-12
+ * @since v0.1.0
*/
public int getExponent(final BaseDimension dimension) {
return this.exponents.getOrDefault(dimension, 0);
@@ -153,6 +161,7 @@ public final class UnitDimension { /**
* @return true if this dimension is a base, i.e. it has one exponent of one and no other nonzero exponents
* @since 2019-01-15
+ * @since v0.1.0
*/
public boolean isBase() {
int oneCount = 0;
@@ -174,6 +183,7 @@ public final class UnitDimension { * other dimension
* @return product of two dimensions
* @since 2018-12-11
+ * @since v0.1.0
*/
public UnitDimension times(final UnitDimension other) {
final Map<BaseDimension, Integer> map = new HashMap<>(this.exponents);
@@ -196,6 +206,7 @@ public final class UnitDimension { * exponent
* @return result of exponientation
* @since 2019-01-15
+ * @since v0.1.0
*/
public UnitDimension toExponent(final int exp) {
final Map<BaseDimension, Integer> map = new HashMap<>(this.exponents);
diff --git a/src/unitConverter/dimension/UnitDimensionTest.java b/src/unitConverter/dimension/UnitDimensionTest.java index 603320b..86db1b8 100755 --- a/src/unitConverter/dimension/UnitDimensionTest.java +++ b/src/unitConverter/dimension/UnitDimensionTest.java @@ -30,22 +30,43 @@ import static unitConverter.dimension.StandardDimensions.VOLUME; import org.junit.jupiter.api.Test; /** + * Tests for {@link UnitDimension}. + * * @author Adrien Hopkins * @since 2018-12-12 + * @since v0.1.0 */ class UnitDimensionTest { + /** + * Tests {@link UnitDimension#equals} + * + * @since 2018-12-12 + * @since v0.1.0 + */ @Test void testEquals() { assertEquals(LENGTH, LENGTH); assertFalse(LENGTH.equals(QUANTITY)); } + /** + * Tests {@code UnitDimension}'s exponentiation + * + * @since 2019-01-15 + * @since v0.1.0 + */ @Test void testExponents() { assertEquals(1, LENGTH.getExponent(SIBaseDimension.LENGTH)); assertEquals(3, VOLUME.getExponent(SIBaseDimension.LENGTH)); } + /** + * Tests {@code UnitDimension}'s multiplication and division. + * + * @since 2018-12-12 + * @since v0.1.0 + */ @Test void testMultiplicationAndDivision() { assertEquals(AREA, LENGTH.times(LENGTH)); diff --git a/src/unitConverter/unit/AbstractUnit.java b/src/unitConverter/unit/AbstractUnit.java index d3d6dbd..24814e8 100644 --- a/src/unitConverter/unit/AbstractUnit.java +++ b/src/unitConverter/unit/AbstractUnit.java @@ -24,13 +24,15 @@ import unitConverter.dimension.UnitDimension; * The default abstract implementation of the {@code Unit} interface. * * @author Adrien Hopkins - * @since 2019-01-25 + * @since 2018-12-22 + * @since v0.1.0 */ public abstract class AbstractUnit implements Unit { /** * The number of units created, including base units. * * @since 2019-01-02 + * @since v0.1.0 */ private static long unitCount = 0; @@ -38,12 +40,14 @@ public abstract class AbstractUnit implements Unit { * The number of base units created. * * @since 2019-01-02 + * @since v0.1.0 */ private static long baseUnitCount = 0; /** * @return number of base units created * @since 2019-01-02 + * @since v0.1.0 */ public static final long getBaseUnitCount() { return baseUnitCount; @@ -52,6 +56,7 @@ public abstract class AbstractUnit implements Unit { /** * @return number of units created * @since 2019-01-02 + * @since v0.1.0 */ public static final long getUnitCount() { return unitCount; @@ -61,6 +66,7 @@ public abstract class AbstractUnit implements Unit { * Increments the number of base units. * * @since 2019-01-15 + * @since v0.1.0 */ public static final void incrementBaseUnitCounter() { baseUnitCount++; @@ -70,6 +76,7 @@ public abstract class AbstractUnit implements Unit { * Increments the number of units. * * @since 2019-01-15 + * @since v0.1.0 */ public static final void incrementUnitCounter() { unitCount++; @@ -79,6 +86,7 @@ public abstract class AbstractUnit implements Unit { * The dimension, or what the unit measures. * * @since 2018-12-22 + * @since v0.1.0 */ private final UnitDimension dimension; @@ -87,6 +95,7 @@ public abstract class AbstractUnit implements Unit { * unit. * * @since 2018-12-22 + * @since v0.1.0 */ private final BaseUnit base; @@ -94,6 +103,7 @@ public abstract class AbstractUnit implements Unit { * The system that this unit is a part of. * * @since 2018-12-23 + * @since v0.1.0 */ private final UnitSystem system; @@ -105,6 +115,7 @@ public abstract class AbstractUnit implements Unit { * @throws NullPointerException * if name, symbol or base is null * @since 2018-12-22 + * @since v0.1.0 */ public AbstractUnit(final BaseUnit base) { this.base = Objects.requireNonNull(base, "base must not be null."); @@ -125,6 +136,7 @@ public abstract class AbstractUnit implements Unit { * @throws NullPointerException * if name, symbol or dimension is null * @since 2018-12-23 + * @since v0.1.0 */ AbstractUnit(final UnitDimension dimension, final UnitSystem system) { // try to set this as a base unit diff --git a/src/unitConverter/unit/BaseUnit.java b/src/unitConverter/unit/BaseUnit.java index 204b1cd..fe36c45 100755 --- a/src/unitConverter/unit/BaseUnit.java +++ b/src/unitConverter/unit/BaseUnit.java @@ -26,12 +26,14 @@ import unitConverter.dimension.UnitDimension; * * @author Adrien Hopkins * @since 2018-12-23 + * @since v0.1.0 */ public final class BaseUnit extends AbstractUnit { /** * Is this unit a full base (i.e. m, s, ... but not N, J, ...) * * @since 2019-01-15 + * @since v0.1.0 */ private final boolean isFullBase; @@ -47,6 +49,7 @@ public final class BaseUnit extends AbstractUnit { * @param symbol * symbol of unit * @since 2018-12-23 + * @since v0.1.0 */ BaseUnit(final UnitDimension dimension, final UnitSystem system) { super(dimension, system); @@ -56,6 +59,7 @@ public final class BaseUnit extends AbstractUnit { /** * @return this unit as a {@code LinearUnit} * @since 2019-01-25 + * @since v0.1.0 */ public LinearUnit asLinearUnit() { return this.times(1); @@ -82,6 +86,7 @@ public final class BaseUnit extends AbstractUnit { * @throws NullPointerException * if other is null * @since 2018-12-22 + * @since v0.1.0 */ public BaseUnit dividedBy(final BaseUnit other) { Objects.requireNonNull(other, "other must not be null."); @@ -97,11 +102,30 @@ public final class BaseUnit extends AbstractUnit { * amount to divide by * @return quotient * @since 2018-12-23 + * @since v0.1.0 */ public LinearUnit dividedBy(final double divisor) { return new LinearUnit(this, 1 / divisor); } + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof BaseUnit)) + return false; + final BaseUnit other = (BaseUnit) obj; + return Objects.equals(this.getSystem(), other.getSystem()) + && Objects.equals(this.getDimension(), other.getDimension()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = result * prime + this.getSystem().hashCode(); + result = result * prime + this.getDimension().hashCode(); + return result; + } + /** * Multiplies this unit by another unit. * @@ -113,6 +137,7 @@ public final class BaseUnit extends AbstractUnit { * @throws NullPointerException * if other is null * @since 2018-12-22 + * @since v0.1.0 */ public BaseUnit times(final BaseUnit other) { Objects.requireNonNull(other, "other must not be null."); @@ -127,7 +152,8 @@ public final class BaseUnit extends AbstractUnit { * @param multiplier * amount to multiply by * @return product - * @since 2018-12-23B + * @since 2018-12-23 + * @since v0.1.0 */ public LinearUnit times(final double multiplier) { return new LinearUnit(this, multiplier); @@ -140,6 +166,7 @@ public final class BaseUnit extends AbstractUnit { * exponent * @return result of exponentiation * @since 2019-01-15 + * @since v0.1.0 */ public BaseUnit toExponent(final int exponent) { return this.getSystem().getBaseUnit(this.getDimension().toExponent(exponent)); diff --git a/src/unitConverter/unit/DefaultUnitPrefix.java b/src/unitConverter/unit/DefaultUnitPrefix.java index 1cce413..d19161b 100755 --- a/src/unitConverter/unit/DefaultUnitPrefix.java +++ b/src/unitConverter/unit/DefaultUnitPrefix.java @@ -19,8 +19,11 @@ package unitConverter.unit; import java.util.Objects; /** + * The default implementation of {@code UnitPrefix}, which contains a multiplier and nothing else. + * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ public final class DefaultUnitPrefix implements UnitPrefix { private final double multiplier; diff --git a/src/unitConverter/unit/LinearUnit.java b/src/unitConverter/unit/LinearUnit.java index e2c9eb2..b786b3b 100644 --- a/src/unitConverter/unit/LinearUnit.java +++ b/src/unitConverter/unit/LinearUnit.java @@ -24,13 +24,15 @@ import unitConverter.dimension.UnitDimension; * A unit that is equal to a certain number multiplied by its base. * * @author Adrien Hopkins - * @since 2019-01-25 + * @since 2018-12-22 + * @since v0.1.0 */ public final class LinearUnit extends AbstractUnit { /** * The value of one of this unit in this unit's base unit * * @since 2018-12-22 + * @since v0.1.0 */ private final double conversionFactor; @@ -43,6 +45,7 @@ public final class LinearUnit extends AbstractUnit { * @param conversionFactor * value of one of this unit in its base * @since 2018-12-23 + * @since v0.1.0 */ LinearUnit(final BaseUnit base, final double conversionFactor) { super(base); @@ -57,6 +60,7 @@ public final class LinearUnit extends AbstractUnit { * @param system * system unit is part of * @since 2019-01-25 + * @since v0.1.0 */ LinearUnit(final UnitDimension dimension, final UnitSystem system, final double conversionFactor) { super(dimension, system); @@ -80,6 +84,7 @@ public final class LinearUnit extends AbstractUnit { * scalar to divide by * @return quotient * @since 2018-12-23 + * @since v0.1.0 */ public LinearUnit dividedBy(final double divisor) { return new LinearUnit(this.getBase(), this.getConversionFactor() / divisor); @@ -94,6 +99,7 @@ public final class LinearUnit extends AbstractUnit { * @throws NullPointerException * if other is null * @since 2018-12-22 + * @since v0.1.0 */ public LinearUnit dividedBy(final LinearUnit other) { Objects.requireNonNull(other, "other must not be null"); @@ -101,14 +107,33 @@ public final class LinearUnit extends AbstractUnit { return new LinearUnit(base, this.getConversionFactor() / other.getConversionFactor()); } + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof LinearUnit)) + return false; + final LinearUnit other = (LinearUnit) obj; + return Objects.equals(this.getBase(), other.getBase()) + && Objects.equals(this.getConversionFactor(), other.getConversionFactor()); + } + /** * @return conversionFactor - * @since 2019-01-25 + * @since 2018-12-22 + * @since v0.1.0 */ public final double getConversionFactor() { return this.conversionFactor; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = result * prime + this.getBase().hashCode(); + result = result * prime + Double.hashCode(this.getConversionFactor()); + return result; + } + /** * Multiplies this unit by a scalar. * @@ -116,6 +141,7 @@ public final class LinearUnit extends AbstractUnit { * scalar to multiply by * @return product * @since 2018-12-23 + * @since v0.1.0 */ public LinearUnit times(final double multiplier) { return new LinearUnit(this.getBase(), this.getConversionFactor() * multiplier); @@ -130,6 +156,7 @@ public final class LinearUnit extends AbstractUnit { * @throws NullPointerException * if other is null * @since 2018-12-22 + * @since v0.1.0 */ public LinearUnit times(final LinearUnit other) { Objects.requireNonNull(other, "other must not be null"); @@ -144,6 +171,7 @@ public final class LinearUnit extends AbstractUnit { * exponent to exponientate unit to * @return exponientated unit * @since 2019-01-15 + * @since v0.1.0 */ public LinearUnit toExponent(final int exponent) { return new LinearUnit(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); diff --git a/src/unitConverter/unit/NonlinearUnits.java b/src/unitConverter/unit/NonlinearUnits.java index f7e257c..ec1874c 100755 --- a/src/unitConverter/unit/NonlinearUnits.java +++ b/src/unitConverter/unit/NonlinearUnits.java @@ -21,6 +21,7 @@ package unitConverter.unit; * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ public final class NonlinearUnits { public static final Unit CELSIUS = new AbstractUnit(SI.KELVIN) { diff --git a/src/unitConverter/unit/SI.java b/src/unitConverter/unit/SI.java index cda42e7..54eb4c5 100644 --- a/src/unitConverter/unit/SI.java +++ b/src/unitConverter/unit/SI.java @@ -28,6 +28,7 @@ import unitConverter.dimension.UnitDimension; * * @author Adrien Hopkins * @since 2018-12-23 + * @since v0.1.0 */ public enum SI implements UnitSystem { SI; @@ -36,6 +37,7 @@ public enum SI implements UnitSystem { * This system's base units. * * @since 2019-01-25 + * @since v0.1.0 */ private static final Set<BaseUnit> baseUnits = new HashSet<>(); diff --git a/src/unitConverter/unit/SIPrefix.java b/src/unitConverter/unit/SIPrefix.java index 39f1a8c..54625fb 100755 --- a/src/unitConverter/unit/SIPrefix.java +++ b/src/unitConverter/unit/SIPrefix.java @@ -17,8 +17,11 @@ package unitConverter.unit; /** + * The SI prefixes. + * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ public enum SIPrefix implements UnitPrefix { DECA(10), HECTO(100), KILO(1e3), MEGA(1e6), GIGA(1e9), TERA(1e12), PETA(1e15), EXA(1e18), ZETTA(1e21), YOTTA( @@ -33,6 +36,7 @@ public enum SIPrefix implements UnitPrefix { * @param multiplier * prefix's multiplier * @since 2019-01-14 + * @since v0.1.0 */ private SIPrefix(final double multiplier) { this.multiplier = multiplier; @@ -41,6 +45,7 @@ public enum SIPrefix implements UnitPrefix { /** * @return value * @since 2019-01-14 + * @since v0.1.0 */ @Override public final double getMultiplier() { diff --git a/src/unitConverter/unit/Unit.java b/src/unitConverter/unit/Unit.java index 9e1375a..54f1423 100755 --- a/src/unitConverter/unit/Unit.java +++ b/src/unitConverter/unit/Unit.java @@ -25,6 +25,7 @@ import unitConverter.dimension.UnitDimension; * * @author Adrien Hopkins * @since 2018-12-22 + * @since v0.1.0 */ public interface Unit { /** @@ -34,6 +35,7 @@ public interface Unit { * unit to test with * @return true if the units are compatible * @since 2019-01-13 + * @since v0.1.0 */ default boolean canConvertTo(final Unit other) { return Objects.equals(this.getBase(), other.getBase()); @@ -53,6 +55,7 @@ public interface Unit { * value expressed in <b>base</b> unit * @return value expressed in <b>this</b> unit * @since 2018-12-22 + * @since v0.1.0 */ double convertFromBase(double value); @@ -70,6 +73,7 @@ public interface Unit { * value expressed in <b>this</b> unit * @return value expressed in <b>base</b> unit * @since 2018-12-22 + * @since v0.1.0 */ double convertToBase(double value); @@ -86,18 +90,21 @@ public interface Unit { * * @return base unit associated with this unit * @since 2018-12-22 + * @since v0.1.0 */ BaseUnit getBase(); /** * @return dimension measured by this unit * @since 2018-12-22 + * @since v0.1.0 */ UnitDimension getDimension(); /** * @return system that this unit is a part of * @since 2018-12-23 + * @since v0.1.0 */ UnitSystem getSystem(); } diff --git a/src/unitConverter/unit/UnitPrefix.java b/src/unitConverter/unit/UnitPrefix.java index cb50fd9..a0c1b7c 100755 --- a/src/unitConverter/unit/UnitPrefix.java +++ b/src/unitConverter/unit/UnitPrefix.java @@ -21,11 +21,13 @@ package unitConverter.unit; * * @author Adrien Hopkins * @since 2019-01-14 + * @since v0.1.0 */ public interface UnitPrefix { /** * @return this prefix's multiplier * @since 2019-01-14 + * @since v0.1.0 */ double getMultiplier(); } diff --git a/src/unitConverter/unit/UnitSystem.java b/src/unitConverter/unit/UnitSystem.java index d641832..ce8c249 100755 --- a/src/unitConverter/unit/UnitSystem.java +++ b/src/unitConverter/unit/UnitSystem.java @@ -25,6 +25,7 @@ import unitConverter.dimension.UnitDimension; * * @author Adrien Hopkins * @since 2018-12-23 + * @since v0.1.0 */ public interface UnitSystem { /** @@ -36,6 +37,7 @@ public interface UnitSystem { * @throws NullPointerException * if dimension is null * @since 2019-01-25 + * @since v0.1.0 */ default BaseUnit getBaseUnit(final UnitDimension dimension) { Objects.requireNonNull(dimension, "dimension must not be null."); @@ -44,7 +46,8 @@ public interface UnitSystem { /** * @return name of system - * @since 2019-01-25 + * @since 2018-12-23 + * @since v0.1.0 */ String getName(); } diff --git a/src/unitConverter/UnitsFileTest.java b/src/unitConverter/unit/UnitTest.java index 8edeab0..c3237eb 100755 --- a/src/unitConverter/UnitsFileTest.java +++ b/src/unitConverter/unit/UnitTest.java @@ -14,18 +14,34 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -package unitConverter; +package unitConverter.unit; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import unitConverter.dimension.StandardDimensions; /** + * Testing the various Unit classes + * * @author Adrien Hopkins - * @since 2019-01-02 + * @since 2018-12-22 */ -class UnitsFileTest { +class UnitTest { + @Test + void testConversion() { + final BaseUnit metre = SI.METRE; + final Unit inch = metre.times(0.0254); + + assertEquals(1.9, inch.convertToBase(75), 0.01); + } + + @Test + void testEquals() { + final BaseUnit metre = SI.METRE; + final Unit meter = SI.SI.getBaseUnit(StandardDimensions.LENGTH); - // @Test - void testReading() { - fail("Not yet implemented."); + assertEquals(metre, meter); } } |