2. Overview
2.1. Project & Product Information
'Savee' is a desktop financial planner application my team of 4 created for our Software Engineering Principles module. Our main project was to morph an existing code into any other software we opted to. We were evaluated based on our ability to work with existing base code and the quality of our new modifications to the existing code.
Savee has a command-line interface (CLI) and graphical user interface created using JavaFX. It is for users who enjoy typing to manage their finances responsibly using a desktop interface. The application revolves around usage of the CLI to manage one’s finances. Users can store a Record
consisting of
name
, moneyflow
, date
and tags
of any form of financial activity in the application.
3. Summary of Contributions
3.1. Major Enhancement: ability to autocomplete text input
-
Function: display a popup-box of suggested words to autocomplete with when user inputs parts of a word.
-
Significance: Improves the product significantly for users who may not be familiar with the software commands and can save time by keying in parts of a command word and simply complete the command using the list of suggested words.
-
Key Highlights: To create an effective autocomplete by words instead of entire text, I needed to accurately read the the entire user input and provide a variable range of suggestions. While it may seem a simple feature, I wrote an extensive amount of code for this feature to ensure the auto complete performed its role successfully for most of the functions in our software.
-
Credits: The Java TextFields (AutoComplete) Library and its inner classes were recreated and tweaked to achieve the necessary aims of our product autocomplete functionality.
3.2. Minor Enhancement #1: ability to find data by tags
-
Function: allows users to find and display all data with a specific attribute
tag
. -
Significance: As mentioned in [Product Information], each data can be categorised with tags. This feature improves the product by providing another means of filtering data according to their needs.
3.3. Minor Enhancement #2: ability to sort data
-
Function: allows users to sort their data by a specific category and in a specific order
-
Significance: This feature improves the product by providing users with different means of manipulating and reorganising their data. This was a simple but much needed functionality. =
3.4. Other Contributions
-
Project management:
-
Pull requests made had to be approved by one other team member and I helped to evaluate pull requests to ensure only necessary changes to the code was merged.
-
Pull Requests reviewed (with non-trivial review comments) #17
-
Added and improved utility methods for comparison and sorting that were easily reusable. (Pull requests #64)
-
Made significant changes to reorganise User Guide user readability. (Pull Request #114)
-
4. Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
4.1. AutoComplete
This section describes the auto completing feature implemented on the input command box which makes the typing interface of Savee more friendly and efficient.
A list of possible words will be displayed in a popup-box under the command box according
to the user input. Word suggestions are displayed when all letters of the current input word match the beginning of
the word in the suggestion word bank. e.g to suggest the word expenditure
user can key in either e
, ex
, exp
and so on, which can all suggest the expected word. However, the expected word must exist in the appropriate word bank
which will be described in [Features].
User may use the ↑ ↓ keys to navigate the list and select a word they wish to complete their input with using Enter. If user does not wish to select a word for completion, user may press ESC or Space or mouseclick anywhere else in the command box to move onto another word. Auto completion is performed word by word and after completing a word, the typing caret will appear at the end of the newly completed word. Previously existing text before and after the completed word will not be lost and will be shifted accordingly.
When the suggestion window is not open, user may use ← and → to navigate the text and may go back to change previously entered texts. These texts will also allow autocompletion if possible, depending on the command in use and parameters already entered.
|
4.1.1. Autocomplete for add
Command
-
Names
-
Inputs starting with
n/
and words that come after it but before the next prefixm/
,d/
ort/
use can be completed with names. -
Suggested words will be suggested based on words used in existing records' names e.g if an earlier inserted record is named
Dinner with Family
, thenDinner
with
Family
can all be possible suggestions.
-
-
Dates
-
Inputs starting with
d/
can be completed with dates. -
Dates must be entered as with the normal constraints and also have 2-digits for both day and months. e.g to have a suggestion of
01-11-2018
to appear, you have to key ind/
0
for that date to appear.d/
1/
will not work. -
Dates that are suggested will also only come from earlier saved records.
-
Can also be completed to
today
orytd
.
-
-
Moneyflow
-
Does not offer auto completion.
-
-
Tags
-
Inputs starting with
t/
can be completed with tags. -
Tags will also only from from earlier saved records' tags and a pre-existing set of tags such as e.g. food, travel, bills, shopping.
-
-
There is no autocompletion restriction on number of names, dates, moneyflow or tag inputs but command will still require the appropriate number of parameters.
4.1.2. Autocomplete for sort
Command
-
Input word suggestions are suggested based on what can still be filled in.
-
If a category has been specified, only an order can be suggested and vice versa.
-
If neither has been specified, then both order and category are possible suggestions.
-
-
There will be no suggestions on parameters that come after the third.
4.1.3. Autocomplete for summary
Command
-
Mode Keyword
-
First parameter after the
summary
keyword can be completed todate
,month
orcategory
.
-
-
Dates
-
Input text can be completed to dates that already exist in records in Savee.
-
Inputs starting with
d/
can be completed with dates as well as the argument that come immediately after the entired/DATE
input as long as there are only whitespaces between them. -
Text can also be completed to
today
orytd
.
-
-
Months
-
Input text can be completed to months with year in the form e.g
nov-2018
. -
Suggestions are currently limited to inputs from
jan-2018
todec-2018
.
-
-
There will be no suggestions on parameters that come after the fourth.
4.1.4. Autocomplete for exportexcel
Command
-
Dates
-
Input text can be completed to dates that already exist in records in Savee.
-
Inputs starting with
d/
can be completed with dates as well as the argument that come immediately after the entired/DATE
input as long as there are only whitespaces between them. -
Text can also be completed to
today
orytd
.
-
-
Directory
-
Does not offer auto-competion.
-
-
There will be no suggestions on parameters that come after the fourth.
4.2. Locating records by tag: findtag
Finds records with tags that match any of the given keywords.
Format: findtag KEYWORD [MORE_KEYWORDS]
Examples:
-
findtag friend
Returns any record tagged withfriend
-
findtag friend food shopping
Returns all records having any of the tagsfriend
,food
, orshopping
4.3. Sorting displayed records : sort
Sorts the list of records in the record book by a category.
There are 3 categories to sort by name
, date
, moneyflow
/money
and
records can be sorted in either ascending order asc
or descending order desc
.
Format: sort [CATEGORY] [ORDER]
Examples:
-
sort date
- Sorts records by date in ascending order. -
sort desc
- Sorts records by name in descending order. -
sort moneyflow desc
- Sorts records by moneyflow in descending order.
5. Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
5.1. Auto Complete Feature
5.1.1. Current Implementation
The autocomplete mechanism is facilitated by the NewAutoCompletionBinding
class. It represents the binding of the
autocomplete window to the CommandBox
and is the component that manages the interactions between the text input and
the contents of the autocomplete list that is displayed in the window. This feature observes the text input in the
CommandBox and displays a list of words in another window under the
CommandBox for the user to select and complete his current focus text - the word he is currently typing.
The key components in this class are the autoCompletionPopup
and the caretChangedListener
that perform the key
functionalities.
caretChangedListener
is an observer that checks the caret in the command box and is triggered whenever the caret
changes its position, whether a character is typed or the caret is moved using the arrow keys. When triggered, it reads
the text in the command box and checks the position of the caret, then extracts the current word of target to be
completed as well as the current input text and the prefix of the current word if any. Extraction is done by tracing back from the caret
position and as well as tracing forward. Any characters that are not a whitespace and are not separated by a whitespace
are considered to be the same word as the current word to be completed. The text before and after the word to completed
are also saved so they will not be lost upon completion.
This listener passes the extracted String input to the CustomSuggestionProvider
through updateSuggestions
.
CustomSuggestionProvider
reads the word to be competed and the input text. It trims and splits the input text and
find the index of the word to completed. It reads the first input first as it is the key command word and performs a
different operation on the input string depending on the command word as well as any possible following parameters.
Functions which are supported by autocomplete will parse the input individually through the different private methods
available in CustomSuggestionProvider
. Once it has decided which set of texts to be the new word suggestion bank,
it calls the CustomSuggestionProvider#updateSuggestions
overloaded method to update the SuggestionProvider
.
After updating the SuggestionProvider
, NewAutoCompletionBinding#SetUserInput
calls onUserInputChanged
which
is responsible for updating the suggestions list according to what the word to be completed is. As this class was
tweaked from the library implementation, the threading involved in this method will not be detailed. It updates
the list of suggestions
by comparing the user input word to the list of suggestions and passes the resultant list to the autoCompletionPopup
which will proceed to display the list of text in the popup below the command box.
Now back to the autoCompletionPopup
, whenever the user highlights a selected word input and selects it, the
autoCompletionPopup#setOnSuggestion
is triggered and will try to complete the word with the selected text and once
completed, it hides the popup and sets the caret to the end of the newly completed word.
The following sequence diagram shows how the auto completion operation works:
5.1.2. Design Considerations
Aspect: Method to Update Suggestion Bank to use for comparison to input word
-
Alternative 1 (current choice): Use listeners to the caret in the command box
-
Pros: Accurate parsing of input and able to detect which word is currently in focus.
-
Cons: Difficult to correctly parse text, as need to avoid whitespaces. Also led to many index array exceptions that can occur when checking the input.
-
-
Alternative 2: Use text listeners in the command box
-
Pros: Simple to implement, similar to library implementation. Safe and minimal room for errors.
-
Cons: Cannot autocomplete by word, can only complete the last word input in the command box. Unable to perform completion for texts before the last word.
-
Aspect: Method to compare input word to Suggestion Bank to obtain displayed list of words
-
Alternative 1 (current choice): Check if suggestion bank word begins with input word
-
Pros: Simple, straightforward autocomplete for users. Users that are already good at typing and spelling will have a breeze using this implementation.
-
Cons: Smaller range of completion texts as users need to accurately type the first few letters before getting a an expected completion suggestion.
-
-
Alternative 2: Check if suggestion bank word contains input word e.g type
tag
→ suggestsfindtag
-
Pros: User can type whichever word is convenient to them to obtain a suggestion they desire. Users who may not know the full spelling of a word and only partially will enjoy this.
-
Cons: Range of texts displayed may be excessive and not appealing to all users.
-
5.2. Find records by tag feature
5.2.1. Current Implementation
The findtag mechanism is also facilitated by ModelManager
. FindTagCommand calls ModelManager#updateFilteredRecords
and passes in different predicates depending on the input by the user.
This feature has only one keyword findtag
and a single working mode which takes in any number of input arguments. The
input given by the user is passed to FindTagCommandParser#parse
to split the desired tags the user wants to search by
into an array of strings. The array of strings is passed into TagsContainsKeywordsPredicate
to create the predicate
for updateFilteredRecordList
required in ModelManager
.
In TagsContainsKeywordsPredicate
, to compare for a match, every keyword in the array is compared
against the set of tags of each record and as long as any tag matches any of the keywords,
the predicate will evaluate to true and allows the FilteredList
to filter out the records that do not fulfil the
predicate.
FindTagCommandParser
returns a FindTagCommand
object which calls updateFilteredRecordList
to set the new predicate
and obtain a new filteredRecords
based on the predicate, which will also trigger an event for the UI to read in and display the new records.
The following sequence diagram shows how the limit operation works:
5.3. Sort records feature
5.3.1. Current Implementation
The sort mechanism is facilitated by ModelManager
. It extends FinancialPlanner
with a component that sorts the
internal list of records. SortCommand calls ModelManager#sortFilteredRecordList
and passes in the category to be
sorted by and the sort order.
This feature has one keyword sort
and takes in arguments of either category or order of sort. Keywords are not
case sensitive.
Category can be either of the following keywords: name
, date
, money
, moneyflow
Order can be either of the following keywords: desc
- descending, asc
- ascending
This feature has 2 different kind of modes as follows:
-
Single Argument Mode - Input argument can be either the category or the order of sort
-
If category specified, records are sorted in ascending order of that category
-
If order specified, records will be sorted by name in the specified order
-
-
Duo Argument Mode - Input arguments must contain only 1 category and only 1 order, and can be input in no particular order
The input given by the user is passed to SortCommandParser
to split the input separated by whitespaces to ensure
there is either only one or two arguments input by the user. These arguments are stored in an array of strings and
the size of the array determines the mode of the command.
The strings are compared to two sets of strings containing the supported categories and orders of the function.
The string of the category and a boolean representing whether the records are to be reversed will then be passed to
ModelManager
to sort the records.
Since the displayed list in the UI is a FilteredList
which is a wrapper for the underlying list UniqueRecordList
structure,
sorting the internal list of records in versionedFinancialPlanner
will post an event that notifies the UI to update
the displayed list.
The following sequence diagram shows how the sort operation works:
5.3.2. Design Considerations
Aspect: Method of sorting data
-
Alternative 1 (current choice): Sort the observable array list in the underlying data structure in
UniqueRecordList
-
Pros: Easy to implement, sorting will be permanent, user need not sort again with every following command
-
Cons: Not very intuitive, user may not have intended to modify the underlying data arrangement instead only want to sort the data just this once for viewing
-
-
Alternative 2: Sort the FilteredList of records obtained after filtering the underlying array list
-
Pros: Does not allow the user to alter the arrangement of the underlying data, and only obtains a sorted version of the read only data.
-
Cons: Unable to sort a FilteredList as it does not support it, implementations could instead use SortedList but it will not be able to perform the filtering function
-