├── .gitignore
├── .travis.yml
├── README.rst
├── bin
└── lib
│ └── .gitignore
├── build.xml
├── build_osx.bash
├── docs
├── DocAnchor.class
├── FAQ.html
├── about.html
├── add.png
├── addfood.png
├── addserving.png
├── apple1.png
├── biomarkers.html
├── biomarkers.png
├── blank.html
├── calendar.png
├── copyyesterday.png
├── cron.css
├── daily.png
├── editpreferences.png
├── export.png
├── food.html
├── help.png
├── help.xml
├── index.html
├── introduction.html
├── limitations.html
├── menu1.png
├── menubar.html
├── navtools.png
├── newfood.png
├── notes.html
├── notes.png
├── nutrient.png
├── nutrient1.png
├── nutrition.png
├── readme.html
├── recipe.html
├── release1.0.html
├── release8.html
├── release9.html
├── summary1.png
├── targets.html
├── targets.png
├── tips.html
├── today.png
├── tomorrow.png
├── toolbar.png
├── track.html
├── user_manager.png
├── users.html
├── webversion.html
├── wv.png
└── yesterday.png
├── lib
├── LGPL.txt
├── crdb_005.jar
├── jcommon-1.0.10.jar
├── jfreechart-1.0.6.jar
├── swingx-core-1.6.2.jar
└── usda_sr28.jar
├── release
├── osx
│ └── Contents
│ │ ├── Info.plist
│ │ ├── MacOS
│ │ └── JavaApplicationStub
│ │ ├── PkgInfo
│ │ └── Resources
│ │ └── cronometer.icns
└── windows
│ ├── cronometer.exe4j
│ └── icon.ico
├── scripts
└── deprecated.py
├── src
├── ca
│ └── spaz
│ │ ├── cron
│ │ ├── Cronometer.java
│ │ ├── ExportWizard.java
│ │ ├── actions
│ │ │ ├── CopyExercisesAction.java
│ │ │ ├── CopyServingsAction.java
│ │ │ ├── CopyServingsToUserAction.java
│ │ │ ├── CreateRecipeAction.java
│ │ │ ├── CutExercisesAction.java
│ │ │ ├── CutServingsAction.java
│ │ │ ├── DeleteExercisesAction.java
│ │ │ ├── DeleteFoodAction.java
│ │ │ ├── DeleteServingsAction.java
│ │ │ ├── EditFoodAction.java
│ │ │ └── ExportFoodAction.java
│ │ ├── datasource
│ │ │ ├── CRDBFoods.java
│ │ │ ├── Datasources.java
│ │ │ ├── DeprecatedFoodProxy.java
│ │ │ ├── FoodDataSource.java
│ │ │ ├── FoodProxy.java
│ │ │ ├── JarXMLFoodDataSource.java
│ │ │ ├── USDAFoods.java
│ │ │ ├── USDAImport
│ │ │ │ ├── USDAFood.java
│ │ │ │ ├── USDAImporter.java
│ │ │ │ └── USDAWeight.java
│ │ │ ├── UserFoods.java
│ │ │ ├── UserFoodsListener.java
│ │ │ ├── XMLFoodLoader.java
│ │ │ └── ZipXMLFoodDataSource.java
│ │ ├── exercise
│ │ │ ├── Exercise.java
│ │ │ ├── ExerciseDialog.java
│ │ │ ├── ExerciseEditor.java
│ │ │ ├── ExerciseEditorListener.java
│ │ │ ├── ExerciseHistory.java
│ │ │ ├── ExercisePanel.java
│ │ │ ├── ExerciseSelection.java
│ │ │ ├── ExerciseTable.java
│ │ │ └── ExerciseTableModel.java
│ │ ├── foods
│ │ │ ├── Food.java
│ │ │ ├── FoodEditor.java
│ │ │ ├── FoodHistory.java
│ │ │ ├── FoodSelectionListener.java
│ │ │ ├── Measure.java
│ │ │ ├── MeasureEditor.java
│ │ │ ├── MeasureWidget.java
│ │ │ ├── NutrientEditorTable.java
│ │ │ ├── NutrientInfo.java
│ │ │ ├── NutrientTable.java
│ │ │ ├── NutrientTableModel.java
│ │ │ ├── Recipe.java
│ │ │ ├── RecipeEditor.java
│ │ │ ├── Serving.java
│ │ │ ├── ServingEditor.java
│ │ │ ├── ServingEditorListener.java
│ │ │ ├── ServingSelection.java
│ │ │ ├── ServingSelectionListener.java
│ │ │ ├── ServingTable.java
│ │ │ └── ServingTableModel.java
│ │ ├── metrics
│ │ │ ├── AddMetricDialog.java
│ │ │ ├── Biomarker.java
│ │ │ ├── BiomarkerDefinitions.java
│ │ │ ├── BiomarkerPanel.java
│ │ │ ├── BiomarkerPanelOld.java
│ │ │ ├── BiometricsHistory.java
│ │ │ ├── Metric.java
│ │ │ ├── MetricChart.java
│ │ │ ├── MetricEditor.java
│ │ │ ├── MetricEditorListener.java
│ │ │ ├── MetricEditorOld.java
│ │ │ ├── MetricSelectionListener.java
│ │ │ ├── MetricTable.java
│ │ │ └── MetricTableModel.java
│ │ ├── notes
│ │ │ ├── Note.java
│ │ │ ├── NoteEditor.java
│ │ │ └── NotesHistory.java
│ │ ├── records
│ │ │ ├── History.java
│ │ │ ├── Record.java
│ │ │ ├── RecordSelectionListener.java
│ │ │ ├── RecordTable.java
│ │ │ └── RecordTableModel.java
│ │ ├── summary
│ │ │ ├── AbstractNutrientSummaryPanel.java
│ │ │ ├── AminoAcidSummaryPanel.java
│ │ │ ├── HTMLSummaryFormat.java
│ │ │ ├── LipidSummaryPanel.java
│ │ │ ├── MacroChart.java
│ │ │ ├── MacroNutrientSummaryPanel.java
│ │ │ ├── MineralSummaryPanel.java
│ │ │ ├── NutrientTable.java
│ │ │ ├── NutritionSummaryPanel.java
│ │ │ ├── ReportWindow.java
│ │ │ ├── SummaryFormat.java
│ │ │ ├── TEXTSummaryFormat.java
│ │ │ ├── TargetBar.java
│ │ │ ├── TargetSummaryChart.java
│ │ │ └── VitaminSummaryPanel.java
│ │ ├── targets
│ │ │ ├── DRI.java
│ │ │ ├── DRITargetModel.java
│ │ │ ├── NutrientInfoPanel.java
│ │ │ ├── Target.java
│ │ │ ├── TargetEditor.java
│ │ │ ├── TargetEditorTable.java
│ │ │ ├── TargetEditorTableModel.java
│ │ │ └── TargetModel.java
│ │ ├── ui
│ │ │ ├── DailySummary.java
│ │ │ ├── ReadMe.java
│ │ │ ├── SearchDialog.java
│ │ │ ├── SearchHit.java
│ │ │ └── SearchPanel.java
│ │ └── user
│ │ │ ├── Favorites.java
│ │ │ ├── User.java
│ │ │ ├── UserChangeListener.java
│ │ │ ├── UserDatePickerDialog.java
│ │ │ ├── UserManager.java
│ │ │ ├── UserManagerDialog.java
│ │ │ └── UserSettingsDialog.java
│ │ ├── gui
│ │ ├── DateChooser.java
│ │ ├── DoubleField.java
│ │ ├── ErrorReporter.java
│ │ ├── HelpBrowser.java
│ │ ├── HyperLabel.java
│ │ ├── IconFont.java
│ │ ├── IntegerField.java
│ │ ├── JMonthChooser.java
│ │ ├── JYearChooser.java
│ │ ├── PercentageBar.java
│ │ ├── PrettyTable.java
│ │ ├── PrettyTableModel.java
│ │ ├── SpazCanvas.java
│ │ ├── SpazCanvasLoader.java
│ │ ├── SpazLayout.java
│ │ ├── SpazMenuBar.java
│ │ ├── SpazPosition.java
│ │ ├── StatusBar.java
│ │ ├── TransferActionListener.java
│ │ ├── TranslucentLabel.java
│ │ ├── TranslucentPanel.java
│ │ ├── TranslucentToolBar.java
│ │ ├── WebViewer.java
│ │ ├── WrappedPanel.java
│ │ └── WrapperDialog.java
│ │ ├── lists
│ │ ├── ListListener.java
│ │ └── SmartList.java
│ │ ├── sql
│ │ ├── Columns.java
│ │ ├── DBRow.java
│ │ ├── SQLColumnSet.java
│ │ ├── SQLDelete.java
│ │ ├── SQLInsert.java
│ │ ├── SQLRow.java
│ │ ├── SQLSelect.java
│ │ ├── SQLSelectableStatement.java
│ │ ├── SQLStatement.java
│ │ └── SQLUpdate.java
│ │ ├── task
│ │ ├── Task.java
│ │ └── TaskListener.java
│ │ ├── util
│ │ ├── BrowserLauncher.java
│ │ ├── CacheMap.java
│ │ ├── CountableInputStream.java
│ │ ├── ImageFactory.java
│ │ ├── JarLoader.java
│ │ ├── Loader.java
│ │ ├── Logger.java
│ │ ├── ProgressListener.java
│ │ ├── Settings.java
│ │ ├── SettingsChangeEvent.java
│ │ ├── SettingsChangeListener.java
│ │ ├── StringUtil.java
│ │ ├── ToolBox.java
│ │ └── XMLNode.java
│ │ └── wizard
│ │ ├── Wizard.java
│ │ └── WizardPanel.java
├── com
│ └── apple
│ │ └── mrj
│ │ ├── MRJAboutHandler.java
│ │ └── MRJQuitHandler.java
├── docs
│ ├── issues.html
│ └── readme.html
├── fontawesome.tff
├── img
│ ├── apple-100x100.png
│ ├── apple-50x50.png
│ └── icon.png
├── menubar.xml
├── nutrients.xml
├── se
│ └── datadosen
│ │ └── component
│ │ └── RiverLayout.java
└── todos.txt
└── start_cronometer.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .*.swp
3 | /bin/ca/
4 | /bin/com/
5 | /bin/se/
6 | /lib/cronometer.jar
7 | /lib/docs.jar
8 | CRONoMeter.app
9 | /tags
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | before_script:
4 | - curl -o ant.tar.gz https://www.apache.org/dist/ant/binaries/apache-ant-1.10.6-bin.tar.gz
5 | - tar xf ant.tar.gz
6 |
7 | script:
8 | - PATH="$PATH:$PWD/apache-ant-1.10.6/bin" ./build_osx.bash
9 | - ls ./CRONoMeter.app
10 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ==========
2 | cronometer
3 | ==========
4 |
5 | .. image:: https://travis-ci.org/myint/cronometer.svg?branch=master
6 | :target: https://travis-ci.org/myint/cronometer
7 | :alt: Build status
8 |
9 | `cronometer` is a nutrition tracking tool. This is a fork of the original_.
10 |
11 | .. _original: http://sourceforge.net/projects/cronometer
12 |
13 |
14 | Build on OS X
15 | =============
16 |
17 | ::
18 |
19 | $ ./build_osx.bash
20 |
21 |
22 |
23 | Build and start on Linux
24 | ========================
25 |
26 | ::
27 |
28 | $ ant
29 | $ ./start_cronometer.sh
30 |
31 |
32 | Download
33 | ========
34 |
35 | https://github.com/myint/cronometer/releases
36 |
37 |
38 | Importing new USDA food database
39 | ================================
40 |
41 | As an example, below is the procedure that was used to upgrade from ``SR26`` to
42 | ``SR28``.
43 |
44 | Unzip the old processed database::
45 |
46 | $ unzip lib/usda_sr26.jar
47 | $ mv usda_sr26 usda_sr28
48 |
49 | Update ``src/ca/spaz/cron/datasource/USDAImport/USDAImporter.java`` to point
50 | to ``sr28``.
51 |
52 | Run the importer to update the old processed data::
53 |
54 | $ java -classpath lib/cronometer.jar \
55 | ca.spaz.cron.datasource.USDAImport.USDAImporter < sr28.zip
56 |
57 | Append deleted items from the old ``foods.index`` into the new
58 | ``deprecated.index``::
59 |
60 | $ ./scripts/deprecated.py usda_sr26/foods.index usda_sr28/foods.index \
61 | >> usda_sr28/deprecated.index
62 |
63 | Create the new JAR::
64 |
65 | $ rm lib/usda_sr26.jar
66 | $ zip -r lib/usda_sr28.jar usda_sr28
67 |
68 | Update ``src/ca/spaz/cron/datasource/USDAFoods.java`` to point to the new JAR.
69 | And update the OS X app to point to the new JAR.
70 |
--------------------------------------------------------------------------------
/bin/lib/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/myint/cronometer/7b7c13d179687188ec5a4fcf6c68ba3669d48f15/bin/lib/.gitignore
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
48 | C:\Documents and Settings\Owner\Application 49 | Data\cronometer 50 |Where "Owner" is your logon ID name, e.g., "John 51 | Smith". 52 | 53 |
The "Application Data" folder is a system folder that will not 54 | be visible unless you specify that hidden files and folders 55 | should be displayed. You can do this from the "Tools" function in 56 | the menu bar of a window.
57 | 58 |59 |Just copy the "cronometer" folder from the old 66 | computer to the corresponding location in the new computer, 67 | install Cronometer from the web on your new computer, and you are 68 | set. The process is similar for other operating systems. 69 | 70 | 71 | -------------------------------------------------------------------------------- /docs/about.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 8 | 9 | 10 |60 | Tools->Folder Options->View 61 | Advanced settings: 62 | Hidden files and folders: 63 | o Show hidden files and folders 64 |65 |
Aaron Davidson | 23 | 24 |aaron@spaz.ca | 25 | 26 |Programming (Lead) | 27 |
Chris Rose | 31 | 32 |chris@offlineblog.com | 33 | 34 |Programming | 35 |
Ryan Dortmans | 39 | 40 |tvstatic | 42 | 43 |Programming | 44 |
Gerald Turnquist | 48 | 49 |geraldt@sasktel.net | 50 | 51 |Programming | 52 |
Simon Werner | 56 | 57 |simon.werner@gmail.com | 58 | 59 |Programming | 60 |
Michael Rae | 64 | 65 |mikalra@cadvision.com | 66 | 67 |Consulting | 68 |
Antonio 72 | Zamora | 73 | 74 |zamora@scientificpsychic.com | 75 | 76 |Technical Writing | 77 |
Library | 90 | 91 |URL | 92 | 93 |Version | 94 | 95 |License | 96 |
---|---|---|---|
JFreeChart | 100 | 101 |http://jfree.org/ | 102 | 103 |1.0.6 | 104 | 105 |LGPL | 107 |
JCommon | 111 | 112 |http://jfree.org/ | 113 | 114 |1.0.10 | 115 | 116 |LGPL | 118 |
SwingX | 122 | 123 |http://swinglabs.org/ | 125 | 126 |1.6.2 | 127 | 128 |LGPL | 130 |
Be careful before drawing conclusions from your nutritional 25 | summaries. Always consult your physician before making 26 | significant changes to your diet or supplementation.
27 | 28 |The data displayed in this software should always be treated 35 | as a rough estimate. The data itself may contain errors or be 36 | incomplete. The USDA food database, for instance, contains 37 | average values for most foods. Local soil and growing conditions 38 | can deviate largely from the average values.
39 | 40 |For instance, values for Vitamin D are missing for many foods 46 | in the USDA nutrition data. Of the 7293 foods listed, only 510 47 | have values for Vitamin D. So if you appear chronically low on 48 | Vitamin D, it may be due to lack of data, not an actual 49 | deficiency in your diet!
50 | 51 |You may write notes to keep track of your moods, or any other 19 | aspect of your diet or exercise. The notes may help you to record 20 | special procedures for food preparation or the timing of your 21 | meals.
When you first run Cronometer you will be asked to set your 19 | nutritional targets for the first time. You can always come back 20 | and change these later. You can either have the program set 21 | default values for your body-type, or manually set them to custom 22 | values.
23 | 24 |Set your nutritional targets for tracking within the program. 25 | Every nutrient has a target minimum and maximum. The minimum 26 | should be set to the minimum amount you want to consume daily. 27 | The maximum should be set to an amount you never want to exceed. 28 | For instance, the toxicity levels of that nutrient should never 29 | be exceeded. As you approach a maximum target, the progress bars 30 | will go bright red to warn you of the danger.
31 | 32 |Clicking 'Set to Dietary Reference Intakes' will set all the 33 | targets to values configured for your weight, height, gender, 34 | age, and activity level. These values are based on the DRIs 35 | published by USDA. Please note that DRIs are not specified for 36 | all nutrients, and so many values will remain unchanged. You may 37 | also edit the targets directly in the table to the right choosing 38 | customized values for your tracking.
39 | 40 |The default nutritional values provided by Cronometer are 41 | based on the official Dietary Reference Intakes (DRI) set by the 42 | USDA. You can change these values to implement any diet. Using 43 | the tabs, navigate to any particular nutrient, double click on 44 | the value that you want to modify, and enter a new value using 45 | the keyboard.
46 | 47 |To ignore certain nutrients you may not be interested in, 48 | toggle off the tracking checkbox for that nutrient to hide it 49 | within the software. Some nutrients are not tracked by default. 50 | Some values have little to no data available in the nutrition 51 | database, and so a user must understand these limitations before 52 | interpreting tracking data for these nutrients.
If the top ranked search result is what you're looking for, 30 | hitting enter will auto-select it. When you select a food, the 31 | keyboard focus automatically transfers to the amount field. 32 | Hitting enter after typing an amount will automatically add the 33 | food. Tab will select the Measure menu and you can use the arrow 34 | keys to page through them. You can actually enter foods without 35 | ever touching the mouse.
36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/today.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myint/cronometer/7b7c13d179687188ec5a4fcf6c68ba3669d48f15/docs/today.png -------------------------------------------------------------------------------- /docs/tomorrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myint/cronometer/7b7c13d179687188ec5a4fcf6c68ba3669d48f15/docs/tomorrow.png -------------------------------------------------------------------------------- /docs/toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myint/cronometer/7b7c13d179687188ec5a4fcf6c68ba3669d48f15/docs/toolbar.png -------------------------------------------------------------------------------- /docs/user_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myint/cronometer/7b7c13d179687188ec5a4fcf6c68ba3669d48f15/docs/user_manager.png -------------------------------------------------------------------------------- /docs/users.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 8 | 9 | 10 |In Cronometer you can track multiple users diets in the same 19 | session. Cronometer will track your food servings, biomarkers, 20 | notes, dietary targets and body profile separately. It is 21 | possible to copy selected foods from one person to another person 22 | and to a given date. When you add a food for one user, it will be 23 | available for all users in the system. The name of the currently 24 | selected user will be displayed in the title bar of the 25 | Cronometer window. When you exit Cronometer and restart it again 26 | another time, the last selected user will be active.
27 | 28 |You can find the user manager dialog in the File menu. The 29 | user manager will allow you to add a user or delete a user. To 30 | switch between users click on the user you wish to switch to, 31 | this will immediately update the servings list to reflect the new 32 | user.
Select the servings you wish to copy to another user, then 39 | from the "Edit" menu select "Copy To...". You will be asked to 40 | select the user to copy the servings to and the date to which 41 | where the copied servings should be placed.
42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/webversion.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 8 | 9 | 10 |List
of IFoodDatasource
instances consisting of
73 | * only those for which isAvailable()
returns true
.
74 | */
75 | public static List getDatasources() {
76 | return sources;
77 | }
78 |
79 | /**
80 | * Closes all data sources in the application.
81 | */
82 | public static void closeAll() {
83 | for (Iterator iter = sources.iterator(); iter.hasNext(); ) {
84 | FoodDataSource element = (FoodDataSource) iter.next();
85 | element.close();
86 | }
87 | // jump start lazy inits
88 | User user = UserManager.getCurrentUser();
89 | user.saveUserData();
90 | }
91 |
92 | /**
93 | * Look up a datasource by name
94 | * @param name the name of the datasource to find
95 | * @return the datasource or null if not found
96 | */
97 | public static FoodDataSource getSource(String name) {
98 | for (Iterator iter = sources.iterator(); iter.hasNext(); ) {
99 | FoodDataSource fds = (FoodDataSource) iter.next();
100 | if (fds.getName().equals(name)) {
101 | return fds;
102 | }
103 | }
104 | return null;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/DeprecatedFoodProxy.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource;
2 |
3 | /**
4 | * In USDA sr19, they decided to 'delete' many old foods that are
5 | * considered out of date or are no longer sold on the market.
6 | *
7 | * This lets us keep those foods for backwards compatibility, but
8 | * lets the program handle them as deprecated food items.
9 | *
10 | * @author adavidson
11 | */
12 | public class DeprecatedFoodProxy extends FoodProxy {
13 |
14 | public DeprecatedFoodProxy(String description, FoodDataSource source, String sourceid) {
15 | super(description, source, sourceid);
16 | }
17 |
18 | public boolean isDeprecated() {
19 | return true;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/FoodProxy.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource;
2 |
3 | import java.lang.ref.SoftReference;
4 |
5 | import ca.spaz.cron.foods.Food;
6 |
7 | /**
8 | * A lightweight proxy for a Food. Just the food description and the ability
9 | * to obtain the full food object if needed. Used primarily for search results.
10 | *
11 | * @author Aaron Davidson
12 | */
13 | public class FoodProxy {
14 | private String description;
15 | private String sourceID;
16 | private FoodDataSource source;
17 | private SoftReference food;
18 | private int references = 0;
19 |
20 | public FoodProxy() {
21 | }
22 |
23 | public FoodProxy(Food f) {
24 | description = f.getDescription();
25 | sourceID = f.getSourceUID();
26 | source = f.getSource();
27 | }
28 |
29 | public FoodProxy(String description, FoodDataSource source, String sourceid) {
30 | this.description = description;
31 | this.source = source;
32 | this.sourceID = sourceid;
33 | }
34 |
35 | public boolean equals(FoodProxy fp) {
36 | if (source != fp.getSource()) {
37 | return false;
38 | }
39 | if (!sourceID.equals(fp.getSourceID())) {
40 | return false;
41 | }
42 | if (!description.equals(fp.getDescription())) {
43 | return false;
44 | }
45 | return true;
46 | }
47 |
48 | public void addReference() {
49 | references++;
50 | }
51 |
52 | public int getReferences() {
53 | return references;
54 | }
55 |
56 | public Food getFood() {
57 | Food f = null;
58 | if (food != null) {
59 | f = (Food)food.get();
60 | }
61 | if (f == null) {
62 | f = source.loadFood(sourceID);
63 | food = new SoftReference(f);
64 | }
65 | return f;
66 | }
67 |
68 | public String getDescription() {
69 | if (description == null) {
70 | description = "";
71 | }
72 | return description;
73 | }
74 |
75 | public void setDescription(String description) {
76 | this.description = description;
77 | }
78 |
79 | public FoodDataSource getSource() {
80 | return source;
81 | }
82 |
83 | public void setSource(FoodDataSource source) {
84 | this.source = source;
85 | }
86 |
87 | public String getSourceID() {
88 | return sourceID;
89 | }
90 |
91 | public void setSourceID(String sourceID) {
92 | this.sourceID = sourceID;
93 | }
94 |
95 | public boolean isDeprecated() {
96 | return false;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/USDAFoods.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource;
2 |
3 | import java.awt.Color;
4 |
5 | import ca.spaz.cron.foods.Food;
6 |
7 |
8 | public class USDAFoods extends JarXMLFoodDataSource {
9 |
10 |
11 | public String getZipFileName() {
12 | return "usda_sr28.jar";
13 | }
14 |
15 | public String getBaseName() {
16 | return "usda_sr28";
17 | }
18 |
19 | public String getName() {
20 | return "USDA";
21 | }
22 |
23 | public String toString() {
24 | return getName();
25 | }
26 |
27 | public boolean isMutable() {
28 | return false;
29 | }
30 |
31 | public void updateFood(Food f) {
32 | }
33 |
34 | public void addFood(Food f) {
35 |
36 | }
37 |
38 | public void removeFood(Food f) {
39 |
40 | }
41 |
42 | public Color getDisplayColor() {
43 | return Color.BLACK;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/USDAImport/USDAFood.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource.USDAImport;
2 |
3 | import java.sql.*;
4 | import java.util.Map;
5 |
6 | import ca.spaz.sql.SQLInsert;
7 | import ca.spaz.util.Logger;
8 |
9 | public class USDAFood {
10 |
11 | int ID;
12 | String ndb_id;
13 | String description;
14 | String foodgroup;
15 | double pCF = 4, fCF = 9, cCF = 4;
16 |
17 |
18 | /**
19 | * Construct from USDB Flat file string
20 | * @param str a string from the USDB sr17 flat file
21 | * @param groups map of ids to food groups
22 | */
23 | public USDAFood(String str, Map groups) {
24 | //~01079~^~0100~^~Milk, reduced fat, fluid, 2% milkfat, with added vitamin A~^~MILK,RED FAT,FLUID,2% MILKFAT,W/ ADDED VIT A~^~~^~~^~Y~^~~^0^~~^^^^
25 | str = str.replaceAll("\\^\\^\\^\\^", "^~~^~~^~~^~~");
26 | str = str.replaceAll("\\^\\^", "^~~^");
27 | str = str.replaceAll("\\^$", "^~~");
28 |
29 | String[] parts = str.split("\\^");
30 | for (int i = 0; i < parts.length; i++) {
31 | parts[i] = parts[i].replaceAll("^~", "");
32 | parts[i] = parts[i].replaceAll("~$", "");
33 | }
34 |
35 | ndb_id = parts[0];
36 | foodgroup = (String) groups.get(parts[1]);
37 | description = parts[2];
38 | if (parts.length == 14) {
39 | try {
40 | pCF = Double.parseDouble(parts[11]);
41 | } catch (NumberFormatException e) {}
42 | try {
43 | fCF = Double.parseDouble(parts[12]);
44 | } catch (NumberFormatException e) {}
45 | try {
46 | cCF = Double.parseDouble(parts[13]);
47 | } catch (NumberFormatException e) {}
48 | } else {
49 | System.out.println("bad parts size?\n\t" + parts.length + "|" + str);
50 | }
51 | }
52 |
53 | public void addToDB(Connection c) {
54 | try {
55 | SQLInsert s = new SQLInsert("Food");
56 | s.getColumns().add("ID", null);
57 | s.getColumns().add("ndb_id", ndb_id);
58 | s.getColumns().add("description", description);
59 | s.getColumns().add("foodgroup", foodgroup);
60 | s.getColumns().add("source", "USDA sr17");
61 | s.getColumns().add("sourceUID", "sql.usda-sr17." + ndb_id);
62 | s.execute(c);
63 |
64 | // get auto-incremented ID
65 | ResultSet rs = c.createStatement().executeQuery("CALL IDENTITY()");
66 | rs.next();
67 | ID = rs.getInt(1);
68 | } catch (SQLException e) {
69 | Logger.error("parseFood(String)", e);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/USDAImport/USDAWeight.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource.USDAImport;
2 |
3 | import java.util.HashMap;
4 |
5 | import ca.spaz.cron.foods.Food;
6 | import ca.spaz.cron.foods.Measure;
7 |
8 | public class USDAWeight {
9 |
10 | String ndb_id;
11 | double amount;
12 | double grams;
13 | String description;
14 |
15 |
16 | public USDAWeight(String str) {
17 | String[] parts = str.split("\\^");
18 | for (int i = 0; i < parts.length; i++) {
19 | parts[i] = parts[i].replaceAll("^~", "");
20 | parts[i] = parts[i].replaceAll("~$", "");
21 | }
22 | ndb_id = parts[0];
23 | if (parts[2].length() == 0) {
24 | amount = 1.0; // hack for bad data
25 | } else {
26 | amount = Double.parseDouble(parts[2]);
27 | }
28 | description = parts[3];
29 | grams = Double.parseDouble(parts[4]);
30 | }
31 |
32 | public void addToDB(HashMap foods) {
33 | Food food = (Food)foods.get(ndb_id);
34 | assert (food != null);
35 | food.getMeasures().add(new Measure(amount, description, grams));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/datasource/UserFoodsListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.datasource;
2 |
3 | public interface UserFoodsListener {
4 |
5 | public void userFoodAdded(FoodProxy fp);
6 | public void userFoodModified(FoodProxy fp);
7 | public void userFoodDeleted(FoodProxy fp);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/exercise/ExerciseDialog.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.exercise;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 |
6 | import javax.swing.*;
7 |
8 | import ca.spaz.util.ToolBox;
9 |
10 | public class ExerciseDialog extends JDialog implements ExerciseEditorListener {
11 |
12 | private ExerciseEditor exerciseEditor;
13 | private JPanel mainPanel;
14 | private boolean abort = true;
15 | private Exercise exercise = null;
16 |
17 | public ExerciseDialog(Frame parent) {
18 | super(parent);
19 | init(parent);
20 | }
21 |
22 | public ExerciseDialog(Dialog parent) {
23 | super(parent);
24 | init(parent);
25 | }
26 |
27 | private void init(Window parent) {
28 | this.setTitle("Add exercise");
29 | this.getContentPane().add(getMainPanel());
30 | this.pack();
31 | ToolBox.centerOver(this, parent);
32 | this.setModal(true);
33 |
34 | // Add escape listener to dismiss window.
35 | getRootPane().registerKeyboardAction(
36 | new ActionListener() {
37 | public void actionPerformed(ActionEvent e) {
38 | dispose();
39 | }
40 | },
41 | KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
42 | JComponent.WHEN_IN_FOCUSED_WINDOW);
43 | }
44 |
45 | public void display(boolean addable) {
46 | getExerciseEditor().getAddButton().setVisible(addable);
47 | this.setVisible(true);
48 | }
49 |
50 | public Exercise getSelectedExercise() {
51 | if (abort) {
52 | return null;
53 | }
54 | return exercise;
55 | }
56 |
57 | public JPanel getMainPanel() {
58 | if (null == mainPanel) {
59 | mainPanel = new JPanel(new BorderLayout(4, 4));
60 | mainPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
61 | mainPanel.add(getExerciseEditor(), BorderLayout.CENTER);
62 | }
63 | return mainPanel;
64 | }
65 |
66 | public ExerciseEditor getExerciseEditor() {
67 | if (exerciseEditor == null) {
68 | exerciseEditor = new ExerciseEditor();
69 | exerciseEditor.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
70 | exerciseEditor.addExerciseEditorListener(this);
71 | }
72 | return exerciseEditor;
73 | }
74 |
75 | public void exerciseChosen(Exercise s) {
76 | exercise = s;
77 | abort = false;
78 | dispose();
79 | }
80 |
81 | public void dispose() {
82 | super.dispose();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/exercise/ExerciseEditorListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.exercise;
2 |
3 | public interface ExerciseEditorListener {
4 | public void exerciseChosen(Exercise e);
5 | }
6 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/exercise/ExerciseHistory.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.exercise;
2 |
3 | import java.util.*;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.cron.records.History;
8 | import ca.spaz.cron.records.Record;
9 |
10 | /**
11 | * The Exercise history for a user.
12 | */
13 | public class ExerciseHistory extends History {
14 |
15 | public String getBaseName() {
16 | return "exercises";
17 | }
18 |
19 | public String getEntryTagName() {
20 | return "exercise";
21 | }
22 |
23 | public Record loadUserEntry(Element item) {
24 | return new Exercise(item);
25 | }
26 |
27 | /**
28 | * Add a new record of a Serving to the history
29 | */
30 | public synchronized void addExercise(Exercise c) {
31 | addEntry(c);
32 | }
33 |
34 | public synchronized List getConsumedOn(Date curDate) {
35 | return getEntriesOn(curDate);
36 | }
37 |
38 | /**
39 | * Copies the servings from one day to another.
40 | * @param fromDate the day to copy from
41 | * @param toDate the day to copy to
42 | * @return the copied servings
43 | */
44 | public synchronized List copyExercisesOn(Date fromDate, Date toDate) {
45 | List prevConsumed = getConsumedOn(fromDate);
46 | List consumed = new ArrayList();
47 | Iterator iter = prevConsumed.iterator();
48 | while (iter.hasNext()) {
49 | Exercise exercise = new Exercise((Exercise) iter.next());
50 | exercise.setDate(toDate);
51 | addExercise(exercise);
52 | }
53 | return consumed;
54 | }
55 |
56 | public synchronized void deleteExercises(List list) {
57 | super.deleteEntries(list);
58 | }
59 |
60 | public synchronized void delete(Exercise exercise) {
61 | super.deleteEntry(exercise);
62 | }
63 |
64 | public void update(Exercise exercise) {
65 | super.updateEntry(exercise);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/exercise/ExercisePanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.exercise;
2 |
3 | import java.awt.BorderLayout;
4 |
5 | import javax.swing.BorderFactory;
6 | import javax.swing.JPanel;
7 |
8 | import ca.spaz.cron.Cronometer;
9 | import ca.spaz.cron.ui.DailySummary;
10 |
11 | public class ExercisePanel extends JPanel {
12 |
13 | private ExerciseTable exerciseTable;
14 |
15 | public ExercisePanel() {
16 | setLayout(new BorderLayout(4, 4));
17 | setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
18 | add(getExerciseTable(), BorderLayout.CENTER);
19 | }
20 |
21 | public ExerciseTable getExerciseTable() {
22 | if (null == exerciseTable) {
23 | exerciseTable = ExerciseTable.getExerciseTable();
24 |
25 | exerciseTable.addExerciseEditorListener(new ExerciseEditorListener() {
26 | public void exerciseChosen(Exercise e) {
27 | DailySummary ds = Cronometer.getDailySummary();
28 | if (ds.isOkToAddServings(ds.getDate(), false)) {
29 | ds.addExercise(e);
30 | }
31 | }
32 | });
33 | }
34 | return exerciseTable;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/exercise/ExerciseSelection.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.exercise;
2 |
3 | import java.awt.datatransfer.*;
4 | import java.io.IOException;
5 | import java.util.List;
6 |
7 |
8 | public class ExerciseSelection implements Transferable {
9 |
10 | public static final DataFlavor exerciseFlavor = new DataFlavor(Exercise[].class, "Exercise");
11 | public static final DataFlavor[] flavors = {exerciseFlavor};
12 |
13 | private Exercise[] exercises;
14 |
15 | public ExerciseSelection(Exercise[] list) {
16 | exercises = list;
17 | }
18 |
19 | public ExerciseSelection(ExerciseTable table) {
20 | List sel = table.getSelectedExercises();
21 | exercises = new Exercise[sel.size()];
22 | sel.toArray(exercises);
23 | }
24 |
25 | public DataFlavor[] getTransferDataFlavors() {
26 | return flavors;
27 | }
28 |
29 | public boolean isDataFlavorSupported(DataFlavor flavor) {
30 | return flavor.equals(exerciseFlavor);
31 | }
32 |
33 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
34 | if (flavor.equals(exerciseFlavor)) {
35 | return (exercises);
36 | } else {
37 | throw new UnsupportedFlavorException(flavor);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/FoodHistory.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 | import java.util.*;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.cron.datasource.FoodProxy;
8 | import ca.spaz.cron.records.History;
9 | import ca.spaz.cron.records.Record;
10 |
11 | /**
12 | * The Serving history for a user.
13 | *
14 | * @author Aaron Davidson
15 | */
16 | public class FoodHistory extends History {
17 |
18 | public String getBaseName() {
19 | return "servings";
20 | }
21 |
22 | public String getEntryTagName() {
23 | return "serving";
24 | }
25 |
26 | public Record loadUserEntry(Element item) {
27 | return new Serving(item);
28 | }
29 |
30 | /**
31 | * Add a new record of a Serving to the history
32 | */
33 | public synchronized void addServing(Serving c) {
34 | addEntry(c);
35 | c.getFoodProxy().addReference();
36 | }
37 |
38 | public synchronized List getConsumedOn(Date curDate) {
39 | return getEntriesOn(curDate);
40 | }
41 |
42 | /**
43 | * Copies the servings from one day to another.
44 | * @param fromDate the day to copy from
45 | * @param toDate the day to copy to
46 | * @return the copied servings
47 | */
48 | public synchronized List copyConsumedOn(Date fromDate, Date toDate) {
49 | List prevConsumed = getConsumedOn(fromDate);
50 | List consumed = new ArrayList();
51 | Iterator iter = prevConsumed.iterator();
52 | while (iter.hasNext()) {
53 | Serving serving = new Serving((Serving) iter.next());
54 | serving.setDate(toDate);
55 | addServing(serving);
56 | }
57 | return consumed;
58 | }
59 |
60 | public synchronized List getServings(FoodProxy fp) {
61 | ArrayList res = new ArrayList();
62 | for (int i = 0; i < entries.size(); i++) {
63 | Serving s = (Serving)entries.get(i);
64 | if (s.getFoodProxy().equals(fp)) {
65 | res.add(s);
66 | }
67 | }
68 | return res;
69 | }
70 |
71 | public synchronized void deleteServings(List list) {
72 | super.deleteEntries(list);
73 | }
74 |
75 | public synchronized void delete(Serving serving) {
76 | super.deleteEntry(serving);
77 | }
78 |
79 | public void update(Serving serving) {
80 | super.updateEntry(serving);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/FoodSelectionListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 | import ca.spaz.cron.datasource.FoodProxy;
4 |
5 | public interface FoodSelectionListener {
6 | public void foodSelected(FoodProxy food);
7 | public void foodDoubleClicked(FoodProxy food);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/NutrientEditorTable.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.util.List;
6 |
7 | import javax.swing.*;
8 | import javax.swing.table.TableColumn;
9 | import javax.swing.table.TableColumnModel;
10 |
11 | import ca.spaz.gui.PrettyTable;
12 |
13 | public class NutrientEditorTable extends JScrollPane {
14 |
15 | NutrientTableModel model;
16 | PrettyTable nutrientTable;
17 |
18 | public NutrientEditorTable(List nutrients) {
19 | model = new NutrientTableModel(nutrients);
20 | setViewportView(getNutrientTable());
21 | getViewport().setBackground(Color.WHITE);
22 | setPreferredSize(new Dimension(350, 185));
23 | }
24 |
25 | public void setMultiplier(double val) {
26 | model.setMultiplier(val);
27 | }
28 |
29 | public void setFood(Food f) {
30 | model.setFood(f);
31 | }
32 |
33 | private JTable getNutrientTable() {
34 | if (null == nutrientTable) {
35 | nutrientTable = new PrettyTable(model);
36 | nutrientTable.getSelectionModel().setSelectionMode(
37 | ListSelectionModel.SINGLE_SELECTION);
38 | nutrientTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
39 | nutrientTable.getTableHeader().setReorderingAllowed(false);
40 | // right align last column
41 | TableColumnModel tcm = nutrientTable.getColumnModel();
42 | TableColumn column = tcm.getColumn(0);
43 | column.setMinWidth(140);
44 | }
45 | return nutrientTable;
46 | }
47 |
48 | public void setEditable(boolean val) {
49 | nutrientTable.setEnabled(val);
50 | }
51 |
52 | public boolean isEditing() {
53 | return nutrientTable.isEditing();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/NutrientTable.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * A base class for a group of related nutrient values Provides common support
7 | * for loading and updating the database.
8 | *
9 | * The nutrient table is expected to have field names that match the names and
10 | * types of the corresponding database table. This greatly simplifies
11 | * maintaining the database and generating UI forms through reflection.
12 | *
13 | * @author davidson
14 | */
15 | public class NutrientTable {
16 |
17 | public double[] nutrients = new double[NutrientInfo.getGlobalList().size()];
18 |
19 | public NutrientTable() {
20 | Arrays.fill(nutrients, -1);
21 | }
22 |
23 | public NutrientTable(NutrientTable nt) {
24 | System.arraycopy(nt.nutrients, 0, nutrients, 0, nutrients.length);
25 | }
26 |
27 | public double getAmount(int index) {
28 | double val = nutrients[index];
29 | if (val < 0) {
30 | val = 0;
31 | }
32 | return val;
33 | }
34 |
35 | public boolean dataExists(int index) {
36 | return nutrients[index] >= 0;
37 | }
38 |
39 | public void setAmount(int index, double val) {
40 | nutrients[index] = val;
41 | }
42 |
43 | /**
44 | * Add the nutrients in the given table to our total
45 | *
46 | * @param toAdd
47 | * the nutrients ratios to add
48 | * @param weight
49 | * multiplier for the amount in the added nutrients
50 | */
51 | public void addFood(NutrientTable toAdd, double weight) {
52 | for (int i = 0; i < nutrients.length; i++) {
53 | nutrients[i] += toAdd.getAmount(i) * weight;
54 | }
55 | }
56 |
57 | public void addFood(Serving food) {
58 | addFood(food.getFood().getNutrients(), food.getGrams() / 100.0);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/ServingEditorListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 |
4 | public interface ServingEditorListener {
5 | public void servingChosen(Serving s);
6 | }
7 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/ServingSelection.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 | import java.awt.datatransfer.*;
4 | import java.io.IOException;
5 | import java.util.List;
6 |
7 |
8 | public class ServingSelection implements Transferable {
9 |
10 | public static final DataFlavor servingFlavor = new DataFlavor(Serving[].class, "Serving");
11 | public static final DataFlavor[] flavors = {servingFlavor};
12 |
13 | private Serving[] servings;
14 |
15 | public ServingSelection(Serving[] list) {
16 | servings = list;
17 | }
18 |
19 | public ServingSelection(ServingTable table) {
20 | List sel = table.getSelectedServings();
21 | servings = new Serving[sel.size()];
22 | sel.toArray(servings);
23 | }
24 |
25 | public DataFlavor[] getTransferDataFlavors() {
26 | return flavors;
27 | }
28 |
29 | public boolean isDataFlavorSupported(DataFlavor flavor) {
30 | return flavor.equals(servingFlavor);
31 | }
32 |
33 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
34 | if (flavor.equals(servingFlavor)) {
35 | return (servings);
36 | } else {
37 | throw new UnsupportedFlavorException(flavor);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/foods/ServingSelectionListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.foods;
2 |
3 |
4 | public interface ServingSelectionListener {
5 | public void servingSelected(Serving s);
6 | public void servingDoubleClicked(Serving s);
7 | public void servingChosen(Serving s);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/BiomarkerPanelOld.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 | import java.awt.*;
4 | import java.util.*;
5 | import java.util.List;
6 |
7 | import javax.swing.BorderFactory;
8 | import javax.swing.JPanel;
9 |
10 | import ca.spaz.cron.user.UserManager;
11 |
12 |
13 | /** This old version is still being used.
14 | *
15 | * The new version is not being used yet, though there are getters that
16 | * reference it.
17 | */
18 | public class BiomarkerPanelOld extends JPanel {
19 | private Date curDate = new Date();
20 | private List curMetrics;
21 | private MetricEditorOld[] editors;
22 | private List biomarkers = new ArrayList();
23 |
24 | public BiomarkerPanelOld() {
25 |
26 | biomarkers = UserManager.getCurrentUser().getBiomarkerDefinitions().getEnabledBiomarkers();
27 | // Create an editor for each enabled biomarker
28 | editors = new MetricEditorOld[biomarkers.size()];
29 | for (int i = 0; i < editors.length; i++) {
30 | Biomarker biomarker = (Biomarker)biomarkers.get(i);
31 | editors[i] = new MetricEditorOld(this, biomarker);
32 | }
33 |
34 | JPanel fp = new JPanel(new GridLayout(4, 4));
35 | fp.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
36 | // Note: the grid bag layout is all done here rather than in Metric Editor so that the
37 | // column alignment works properly across the entire grid.
38 | JPanel ed = new JPanel(new GridBagLayout());
39 | GridBagConstraints c = new GridBagConstraints();
40 | c.fill = GridBagConstraints.NONE;
41 | c.weightx = 0.0;
42 | c.insets = new Insets(8, 8, 8, 8);
43 | for (int i = 0; i < editors.length; i++) {
44 | c.gridx = 0;
45 | c.gridy = i;
46 | ed.add(editors[i].getLabel(), c);
47 | c.gridx = 1;
48 | c.gridy = i;
49 | ed.add(editors[i].getEntryField(), c);
50 | c.gridx = 2;
51 | c.gridy = i;
52 | ed.add(editors[i].getSaveButton(), c);
53 | c.gridx = 3;
54 | c.gridy = i;
55 | ed.add(editors[i].getDeleteButton(), c);
56 | c.gridx = 4;
57 | c.gridy = i;
58 | ed.add(editors[i].getPlotButton(), c);
59 | }
60 | JPanel x = new JPanel(new BorderLayout());
61 | x.add(ed, BorderLayout.NORTH);
62 | setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
63 | setLayout(new BorderLayout(4, 4));
64 | add(x, BorderLayout.WEST);
65 |
66 | // Avoid ugly color mismatch with background.
67 | fp.setOpaque(false);
68 | ed.setOpaque(false);
69 | x.setOpaque(false);
70 | }
71 |
72 | public void setDate(Date d) {
73 | this.curDate = d;
74 | curMetrics = null;
75 | for (int i = 0; i < editors.length; i++) {
76 | editors[i].setMetrics(getMetrics());
77 | }
78 | }
79 |
80 | public Date getDate() {
81 | return curDate;
82 | }
83 |
84 | private List getMetrics() {
85 | if (curMetrics == null) {
86 | curMetrics = UserManager.getCurrentUser().getBiometrics(curDate);
87 | }
88 | return curMetrics;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/BiometricsHistory.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 | import java.util.*;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.cron.records.History;
8 | import ca.spaz.cron.records.Record;
9 |
10 | /**
11 | * The Biometrics history for a user.
12 | *
13 | * @author Aaron Davidson
14 | */
15 | public class BiometricsHistory extends History {
16 |
17 | public BiometricsHistory() {
18 | super();
19 | }
20 |
21 | public String getBaseName() {
22 | return "metrics";
23 | }
24 |
25 | public String getEntryTagName() {
26 | return "metric";
27 | }
28 |
29 | public Record loadUserEntry(Element item) {
30 | return new Metric(item);
31 | }
32 |
33 | /**
34 | * Add a new record of a Metric to the history
35 | */
36 | public synchronized void addMetric(Metric m) {
37 | addEntry(m);
38 | }
39 |
40 | public synchronized List getMetricsOn(Date curDate) {
41 | return getEntriesOn(curDate);
42 | }
43 |
44 | public List getMetricsOfType(String type) {
45 | ArrayList res = new ArrayList();
46 | for (int i = 0; i < entries.size(); i++) {
47 | Metric m = (Metric)entries.get(i);
48 | if (m.getName().equals(type)) {
49 | res.add(m);
50 | }
51 | }
52 | return res;
53 | }
54 |
55 | public void delete(Metric m) {
56 | deleteEntry(m);
57 | }
58 |
59 | public void update(Metric m) {
60 | updateEntry(m);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/Metric.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 | import java.util.Date;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.cron.records.Record;
8 | import ca.spaz.util.XMLNode;
9 |
10 | public class Metric implements Comparable, Record {
11 | public static String WEIGHT_UNIT = null;
12 |
13 | private String name;
14 | private Number value;
15 | private Date date;
16 |
17 | public Metric() {
18 | setDate(new Date());
19 | }
20 |
21 | public Metric(String name, Date d) {
22 | setName(name);
23 | setDate(d);
24 | }
25 |
26 | public Metric(Biomarker biomarker) {
27 | setName(biomarker.getName());
28 | }
29 |
30 | public Metric(Element e) {
31 | load(e);
32 | }
33 |
34 | public void load(Element e) {
35 | setName(e.getAttribute("name"));
36 | setValue(e.getAttribute("value"));
37 | setDate(new Date(Long.parseLong(e.getAttribute("date"))));
38 | }
39 |
40 | /**
41 | * Compares two metrics by date for sorting.
42 | */
43 | public int compareTo(Object object) {
44 | return date.compareTo(((Metric)object).getDate());
45 | }
46 |
47 | public Date getDate() {
48 | return date;
49 | }
50 |
51 | public void setDate(Date date) {
52 | this.date = date;
53 | }
54 |
55 | public String getName() {
56 | return name;
57 | }
58 |
59 | public void setName(String name) {
60 | this.name = name;
61 | }
62 |
63 | public Number getValue() {
64 | return value;
65 | }
66 |
67 | public void setValue(String value) {
68 | this.value = new Double(value);
69 | }
70 |
71 | public void setValue(Number value) {
72 | this.value = value;
73 | }
74 |
75 | public XMLNode toXML() {
76 | XMLNode node = new XMLNode("metric");
77 | node.addAttribute("name", getName());
78 | node.addAttribute("date", getDate().getTime());
79 | node.addAttribute("value", getValue().doubleValue());
80 | if (name.equals("Weight") && WEIGHT_UNIT != null) {
81 | node.addAttribute("unit", WEIGHT_UNIT);
82 | }
83 | return node;
84 | }
85 |
86 | public String toString() {
87 | return getName() + "-" + getDate() + "-" + getValue();
88 | }
89 |
90 | public Record copy() {
91 | Metric m = new Metric();
92 | m.setDate(date);
93 | m.setName(name);
94 | m.setValue(value);
95 | return m;
96 | }
97 |
98 | public boolean isLoaded() {
99 | return true;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/MetricEditorListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 |
4 | public interface MetricEditorListener {
5 | public void metricSelected(Metric metric);
6 | public void metricDoubleClicked(Metric metric);
7 | public void metricChosen(Metric metric);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/MetricSelectionListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 |
4 | public interface MetricSelectionListener {
5 | public void metricSelected(Metric metric);
6 | public void metricDoubleClicked(Metric metric);
7 | public void metricChosen(Metric metric);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/MetricTable.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.util.List;
6 |
7 | import javax.swing.*;
8 | import javax.swing.table.DefaultTableCellRenderer;
9 | import javax.swing.table.TableColumnModel;
10 |
11 | import ca.spaz.cron.Cronometer;
12 | import ca.spaz.cron.records.RecordTable;
13 | import ca.spaz.cron.user.UserManager;
14 |
15 | public class MetricTable extends RecordTable {
16 |
17 | public MetricTable() {
18 | super(new MetricTableModel());
19 | setTitle("BioMarkers");
20 | }
21 |
22 | public void doAddNewEntry() {
23 | AddMetricDialog md = new AddMetricDialog(JOptionPane.getFrameForComponent(this));
24 | md.display(true);
25 | md.getListPanel().requestFocus();
26 |
27 | Metric metric = md.getSelectedMetric();
28 | if (metric != null) {
29 | metric.setDate(Cronometer.getInstance().getDailySummary().getDate());
30 | addMetric(metric);
31 | fireUserEntryChosen(metric);
32 | }
33 | }
34 |
35 | private JComponent makeJScrollPane() {
36 | JScrollPane jsp = new JScrollPane(getTable());
37 | jsp.setPreferredSize(new Dimension(400, 250));
38 | jsp.getViewport().setBackground(Color.WHITE);
39 | jsp.setBorder(BorderFactory.createEtchedBorder());
40 | return jsp;
41 | }
42 |
43 | protected void initTable() {
44 | table.setColumnSelectionAllowed(false);
45 | table.getSelectionModel().setSelectionMode(
46 | ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
47 | table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
48 | table.getTableHeader().setReorderingAllowed(false);
49 |
50 | table.getColumnModel().getColumn(MetricTableModel.TIME_COL).setMinWidth(60);
51 | table.getColumnModel().getColumn(MetricTableModel.BIOMARKER_COL).setMinWidth(100);
52 | table.getColumnModel().getColumn(MetricTableModel.VALUE_COL).setMaxWidth(60);
53 | table.getColumnModel().getColumn(MetricTableModel.UNITS_COL).setMinWidth(60);
54 |
55 | TableColumnModel tcm = table.getColumnModel();
56 | // Center the time column
57 | DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
58 | renderer.setHorizontalAlignment(SwingConstants.CENTER);
59 | tcm.getColumn(MetricTableModel.TIME_COL).setCellRenderer(renderer);
60 | // Right align value column
61 | renderer = new DefaultTableCellRenderer();
62 | renderer.setHorizontalAlignment(SwingConstants.RIGHT);
63 | tcm.getColumn(MetricTableModel.VALUE_COL).setCellRenderer(renderer);
64 | }
65 |
66 | public void setMetrics(List metrics) {
67 | getMetricTableModel().setMetrics(metrics);
68 | fireStateChangedEvent();
69 | }
70 |
71 | public List getMetrics() {
72 | return getMetricTableModel().getMetrics();
73 | }
74 |
75 | public void addMetric(Metric metric) {
76 | model.addUserEntry(metric);
77 | UserManager.getCurrentUser().getBiometricsHistory().addMetric(metric);
78 | fireStateChangedEvent();
79 | }
80 |
81 | public MetricTableModel getMetricTableModel() {
82 | return (MetricTableModel)model;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/metrics/MetricTableModel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.metrics;
2 |
3 | import java.text.*;
4 | import java.util.List;
5 |
6 | import ca.spaz.cron.user.UserManager;
7 | import ca.spaz.cron.records.RecordTableModel;
8 |
9 | /**
10 | * MetricTableModel is the model for displaying a table of biomarker measurements.
11 | */
12 | public class MetricTableModel extends RecordTableModel {
13 | public static final int TIME_COL = 0;
14 | public static final int BIOMARKER_COL = 1;
15 | public static final int VALUE_COL = 2;
16 | public static final int UNITS_COL = 3;
17 |
18 | public static String[] columnNames = { "Time", "Biomarker", "Value", "Units" };
19 |
20 | private static final DecimalFormat kcalf = new DecimalFormat("######0.0");
21 | private static final DecimalFormat amountf = new DecimalFormat("######0.##");
22 | private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
23 |
24 | public void setMetrics(List list) {
25 | setUserEntrys(list);
26 | }
27 |
28 | public List getMetrics() {
29 | return getUserEntrys();
30 | }
31 |
32 | public Class getColumnClass(int col) {
33 | Object o = getValueAt(0, col);
34 | if (o != null) {
35 | return o.getClass();
36 | }
37 | return String.class;
38 | }
39 |
40 | public int getColumnCount() {
41 | return columnNames.length;
42 | }
43 |
44 | public String getColumnName(int col) {
45 | return columnNames[col].toString();
46 | }
47 |
48 | public Metric getMetric(int i) {
49 | return (Metric)getUserEntry(i);
50 | }
51 |
52 | public int getNumMetrics() {
53 | return getUserEntrys().size();
54 | }
55 |
56 | public int getRowCount() {
57 | return getUserEntrys().size();
58 | }
59 |
60 | public Object getValueAt(int row, int col) {
61 | Metric metric = getMetric(row);
62 | if (metric != null) {
63 | switch (col) {
64 | case TIME_COL:
65 | return timeFormat.format(metric.getDate());
66 | case UNITS_COL:
67 | return (UserManager.getCurrentUser().getBiomarkerDefinitions().getBiomarker(metric.getName()).getUnits());
68 | case BIOMARKER_COL:
69 | return metric.getName();
70 | case VALUE_COL:
71 | return metric.getValue();
72 | }
73 | }
74 | return "";
75 | }
76 |
77 | public boolean isCellEditable(int row, int col) {
78 | if (col == VALUE_COL) {
79 | return true;
80 | }
81 | return false;
82 | }
83 |
84 | public void setValueAt(Object value, int row, int col) {
85 | if (row < 0 || row >= getRowCount()) {
86 | return;
87 | }
88 | Metric metric = getMetric(row);
89 | if (value == null || metric == null) {
90 | return;
91 | }
92 | if (col == VALUE_COL) {
93 | try {
94 | metric.setValue((Double)value);
95 | } catch (NumberFormatException e) {}
96 | }
97 | fireTableRowsUpdated(row, row);
98 | }
99 |
100 | public String getToolTipText(int r, int c) {
101 | return null;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/notes/Note.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.notes;
2 |
3 | import java.util.Date;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.cron.records.Record;
8 | import ca.spaz.util.XMLNode;
9 |
10 | public class Note implements Record {
11 | private long time = System.currentTimeMillis();
12 | private String note;
13 |
14 | public Record copy() {
15 | Note n = new Note();
16 | n.setTime(time);
17 | setNote(note);
18 | return n;
19 | }
20 |
21 | public String getNote() {
22 | return note;
23 | }
24 |
25 | public void setDate(Date d) {
26 | time = d.getTime();
27 | }
28 |
29 | public void setTime(long t) {
30 | time = t;
31 | }
32 |
33 | public Date getDate() {
34 | return new Date(time);
35 | }
36 |
37 | public void load(Element e) {
38 | this.time = XMLNode.getLong(e, "time");
39 | this.note = XMLNode.getTextContent(e);
40 | }
41 |
42 | public XMLNode toXML() {
43 | XMLNode node = new XMLNode("note");
44 | node.addAttribute("time", time);
45 | if (note != null) {
46 | node.setText(note);
47 | }
48 | return node;
49 | }
50 |
51 | public void setNote(String n) {
52 | this.note = n;
53 | }
54 |
55 | public boolean isLoaded() {
56 | return true;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/notes/NoteEditor.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.notes;
2 |
3 | import java.awt.BorderLayout;
4 | import java.awt.Dimension;
5 | import java.awt.event.FocusEvent;
6 | import java.awt.event.FocusListener;
7 | import java.util.Date;
8 |
9 | import javax.swing.*;
10 | import javax.swing.text.BadLocationException;
11 |
12 | import ca.spaz.cron.user.UserManager;
13 |
14 | public class NoteEditor extends JPanel implements FocusListener {
15 |
16 | private JScrollPane jsp;
17 | private JTextArea edit;
18 | private Date curDate = null;
19 |
20 | public NoteEditor() {
21 | setLayout(new BorderLayout(4, 4));
22 | setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
23 | jsp = new JScrollPane(getEditor());
24 | jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
25 | jsp.setPreferredSize(new Dimension(200, 200));
26 | add(jsp, BorderLayout.CENTER);
27 | }
28 |
29 | private JTextArea getEditor() {
30 | if (edit == null) {
31 | edit = new JTextArea();
32 | edit.setWrapStyleWord(true);
33 | edit.setLineWrap(true);
34 | edit.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
35 | edit.addFocusListener(this);
36 | }
37 | return edit;
38 | }
39 |
40 | public void clear() {
41 | SwingUtilities.invokeLater(new Runnable() {
42 | public void run() {
43 | try {
44 | getEditor().getDocument().remove(0, getEditor().getDocument().getLength());
45 | } catch (BadLocationException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 | });
50 | }
51 |
52 | public String getContents() {
53 | return getEditor().getText();
54 | }
55 |
56 | public void setContents(final String txt) {
57 | SwingUtilities.invokeLater(new Runnable() {
58 | public void run() {
59 | getEditor().setText(txt);
60 | getEditor().setCaretPosition(0);
61 | }
62 | });
63 | }
64 |
65 | public void saveCurrentNote() {
66 | if (curDate != null) {
67 | UserManager.getCurrentUser().setNotes(getContents(), curDate);
68 | }
69 | }
70 |
71 | private String curNote = null;
72 |
73 | public void setDate(Date d) {
74 | curDate = d;
75 | clear();
76 | curNote = UserManager.getCurrentUser().getNotes(curDate);
77 | if (curNote == null) {
78 | curNote = "";
79 | }
80 | setContents(curNote);
81 | }
82 |
83 | public void focusGained(FocusEvent arg0) {
84 | // Do nothing
85 | }
86 |
87 | /**
88 | * Invoked when the text area loses the keyboard focus.
89 | * This will not be invoked when the user clicks on the next/previous day button.
90 | */
91 | public void focusLost(FocusEvent e) {
92 | if (curDate != null) {
93 | saveCurrentNote();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/notes/NotesHistory.java:
--------------------------------------------------------------------------------
1 |
2 | package ca.spaz.cron.notes;
3 |
4 | import java.util.Date;
5 | import java.util.List;
6 |
7 | import org.w3c.dom.Element;
8 |
9 | import ca.spaz.cron.records.History;
10 | import ca.spaz.cron.records.Record;
11 |
12 | /**
13 | * The notes (daily diary) history for a user.
14 | *
15 | * @author Aaron Davidson
16 | */
17 | public class NotesHistory extends History {
18 |
19 | private static final String NOTES_HISTORY_FILE = "notes.xml";
20 |
21 |
22 | public NotesHistory() {
23 | super();
24 | }
25 |
26 | public String getBaseName() {
27 | return "notes";
28 | }
29 |
30 | public String getEntryTagName() {
31 | return "note";
32 | }
33 |
34 | public Record loadUserEntry(Element e) {
35 | Note note = new Note();
36 | note.load(e);
37 | return note;
38 | }
39 |
40 | public synchronized String getNote(Date date) {
41 | String str = null;
42 | List list = getEntriesOn(date);
43 | if (list != null) {
44 | if (list.size() > 0) {
45 | Note note = (Note)list.get(0);
46 | str = note.getNote();
47 | }
48 | }
49 | return str;
50 | }
51 |
52 | public synchronized void setNote(String note, Date d) {
53 | if (note != null && note.length() == 0) {
54 | note = null;
55 | }
56 | List list = getEntriesOn(d);
57 | if (list.size() > 0) {
58 | Note n = (Note)list.get(0);
59 | if (note == null) {
60 | deleteEntry(n);
61 | } else if (!n.getNote().equals(note)) {
62 | n.setNote(note);
63 | updateEntry(n);
64 | }
65 | } else if (note != null) {
66 | Note n = new Note();
67 | n.setDate(d);
68 | n.setNote(note);
69 | addEntry(n);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/records/Record.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.records;
2 |
3 | import java.util.Date;
4 |
5 | import org.w3c.dom.Element;
6 |
7 | import ca.spaz.util.XMLNode;
8 |
9 | public interface Record {
10 |
11 | public Date getDate();
12 |
13 | public XMLNode toXML();
14 |
15 | public void load(Element e);
16 |
17 | public Record copy();
18 |
19 | public boolean isLoaded();
20 | }
21 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/records/RecordSelectionListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.records;
2 |
3 |
4 | public interface RecordSelectionListener {
5 |
6 | public void recordSelected(Record record);
7 |
8 | public void recordDoubleClicked(Record record);
9 |
10 | public void recordChosen(Record record);
11 | }
12 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/records/RecordTableModel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.records;
2 |
3 | import java.awt.Component;
4 | import java.text.DateFormat;
5 | import java.text.SimpleDateFormat;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import ca.spaz.gui.PrettyTable;
10 | import ca.spaz.gui.PrettyTableModel;
11 |
12 | public abstract class RecordTableModel extends PrettyTableModel {
13 | private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
14 |
15 | private List entries = new ArrayList();
16 |
17 | public void setUserEntrys(List list) {
18 | entries = list;
19 | fireTableDataChanged();
20 | }
21 |
22 | public List getUserEntrys() {
23 | return entries;
24 | }
25 |
26 | public Class getColumnClass(int col) {
27 | Object o = getValueAt(0, col);
28 | if (o != null) {
29 | return o.getClass();
30 | }
31 | return String.class;
32 | }
33 |
34 | public Record getUserEntry(int i) {
35 | if (i < 0 || i >= entries.size()) {
36 | return null;
37 | }
38 | return (Record) entries.get(i);
39 | }
40 |
41 | public int getNumUserEntrys() {
42 | return entries.size();
43 | }
44 |
45 | public int getRowCount() {
46 | return entries.size();
47 | }
48 |
49 | public void delete(Record UserEntry) {
50 | entries.remove(UserEntry);
51 | fireTableDataChanged();
52 | }
53 |
54 | public void addUserEntry(Record userEntry) {
55 | entries.add(userEntry);
56 | fireTableDataChanged();
57 | }
58 |
59 | public void sort() {
60 | // no sorting in this table for now.
61 | }
62 |
63 | /**
64 | * Allows custom rendering for a row and column. Can just return c, if no
65 | * changes to default are desired.
66 | * @param c the component used for rendering the cell
67 | * @param row the row to render
68 | * @param col the column to render
69 | * @return a custom rendering component
70 | */
71 | public Component customRender(Component c, PrettyTable table, int row, int col) {
72 | return c;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/AbstractNutrientSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.util.Iterator;
6 | import java.util.List;
7 |
8 | import javax.swing.*;
9 |
10 | import ca.spaz.cron.foods.NutrientInfo;
11 | import ca.spaz.cron.targets.Target;
12 | import ca.spaz.cron.user.UserManager;
13 |
14 | public abstract class AbstractNutrientSummaryPanel extends JPanel {
15 |
16 | protected NutrientTable nutrientTable;
17 | protected JScrollPane scrollPane;
18 | protected abstract List getNutrientList();
19 | protected abstract String getCategoryName();
20 |
21 | protected NutrientTable getNutrientTable() {
22 | if (nutrientTable == null) {
23 | nutrientTable = new NutrientTable(getNutrientList());
24 | }
25 | return nutrientTable;
26 | }
27 |
28 | protected JScrollPane getNutrientTablePane() {
29 | if (scrollPane == null) {
30 | scrollPane = new JScrollPane(getNutrientTable());
31 | scrollPane.setMinimumSize(new Dimension(400, 180));
32 | scrollPane.setPreferredSize(new Dimension(500, 180));
33 | scrollPane.getViewport().setBackground(Color.WHITE);
34 | scrollPane.setBorder(BorderFactory.createEtchedBorder());
35 | scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
36 | }
37 | return scrollPane;
38 | }
39 |
40 | public void update(List consumed) {
41 | getNutrientTable().update(consumed);
42 | }
43 |
44 | /**
45 | * Look through all nutrients and see what overall percentage of the targets
46 | * are completed.
47 | */
48 | public double getTargetCompletion(boolean average) {
49 | double total = 0;
50 | double value = 0;
51 | double valueFull = 0;
52 |
53 | Iterator iter = getNutrientList().iterator();
54 | while (iter.hasNext()) {
55 | NutrientInfo ni = (NutrientInfo)iter.next();
56 | Target target = UserManager.getCurrentUser().getTarget(ni);
57 | if (target.getMin() > 0 && UserManager.getCurrentUser().isTracking(ni)) {
58 | double amount = getNutrientTable().getAmount(ni);
59 | valueFull += amount / target.getMin();
60 | if (amount < target.getMin()) {
61 | value += amount / target.getMin();
62 | } else {
63 | value++;
64 | }
65 | total++;
66 | }
67 | }
68 | if (average) {
69 | return valueFull / total;
70 | } else {
71 | return value / total;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/AminoAcidSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.BorderLayout;
4 | import java.util.List;
5 |
6 | import javax.swing.BorderFactory;
7 |
8 | import ca.spaz.cron.foods.NutrientInfo;
9 |
10 | public class AminoAcidSummaryPanel extends AbstractNutrientSummaryPanel {
11 |
12 | public AminoAcidSummaryPanel() {
13 | setLayout(new BorderLayout());
14 | setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
15 | add(getNutrientTablePane(), BorderLayout.CENTER);
16 | }
17 |
18 | protected List getNutrientList() {
19 | return NutrientInfo.getAminoAcids();
20 | }
21 |
22 | protected String getCategoryName() {
23 | return "Amino Acids";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/LipidSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.BorderLayout;
4 | import java.util.List;
5 |
6 | import javax.swing.BorderFactory;
7 |
8 | import ca.spaz.cron.foods.NutrientInfo;
9 |
10 | public class LipidSummaryPanel extends AbstractNutrientSummaryPanel {
11 |
12 | public LipidSummaryPanel() {
13 | setLayout(new BorderLayout());
14 | setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
15 | add(getNutrientTablePane(), BorderLayout.CENTER);
16 | }
17 |
18 | protected List getNutrientList() {
19 | return NutrientInfo.getLipids();
20 | }
21 |
22 | protected String getCategoryName() {
23 | return "Lipids";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/MacroChart.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.*;
4 |
5 | import javax.swing.JComponent;
6 |
7 | public class MacroChart extends JComponent {
8 |
9 | private double protein;
10 | private double carbs;
11 | private double fat;
12 |
13 | public double getCarbs() {
14 | return carbs;
15 | }
16 |
17 | public void setCarbs(double carbs) {
18 | this.carbs = carbs;
19 | repaint();
20 | }
21 |
22 | public double getFat() {
23 | return fat;
24 | }
25 |
26 | public void setFat(double fat) {
27 | this.fat = fat;
28 | repaint();
29 | }
30 |
31 | public double getProtein() {
32 | return protein;
33 | }
34 |
35 | public void setProtein(double protein) {
36 | this.protein = protein;
37 | repaint();
38 | }
39 |
40 | public void paint(Graphics g) {
41 | Graphics2D g2d = (Graphics2D)g;
42 | g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f));
43 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
44 | double total = protein + carbs + fat;
45 | int w = getWidth();
46 | int h = getHeight();
47 | int min = w < h ? w : h;
48 | g.setColor(Color.BLACK);
49 |
50 | g.setColor(Color.GREEN);
51 | int amount = 0;
52 | g.fillArc(2, 2, min - 4, min - 4, amount, (int)(360 * (protein / total)));
53 | amount += (int)(360 * (protein / total));
54 |
55 | g.setColor(Color.BLUE);
56 | g.fillArc(2, 2, min - 4, min - 4, amount, (int)(360 * (carbs / total)));
57 | amount += (int)(360 * (carbs / total));
58 |
59 | g.setColor(Color.RED);
60 | g.fillArc(2, 2, min - 4, min - 4, amount, (int)(360 * (fat / total)));
61 |
62 | g.setColor(Color.GREEN);
63 | g.drawString(Integer.toString((int)(100 * (protein / total))), 5, h / 2);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/MacroNutrientSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.BorderLayout;
4 | import java.util.Iterator;
5 | import java.util.List;
6 |
7 | import javax.swing.BorderFactory;
8 |
9 | import ca.spaz.cron.foods.NutrientInfo;
10 | import ca.spaz.cron.foods.Serving;
11 |
12 | public class MacroNutrientSummaryPanel extends AbstractNutrientSummaryPanel {
13 | public MacroNutrientSummaryPanel() {
14 | setLayout(new BorderLayout());
15 | setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
16 | add(getNutrientTablePane(), BorderLayout.CENTER);
17 | }
18 |
19 | protected String getCategoryName() {
20 | return "General";
21 | }
22 |
23 | protected List getNutrientList() {
24 | return NutrientInfo.getMacroNutrients();
25 | }
26 |
27 | private double getAmount(List servings, NutrientInfo ni) {
28 | double total = 0;
29 | for (Iterator iter = servings.iterator(); iter.hasNext(); ) {
30 | Serving serving = (Serving) iter.next();
31 | double weight = serving.getGrams() / 100.0;
32 | total += weight * serving.getFood().getNutrientAmount(ni);
33 | }
34 | return total;
35 | }
36 |
37 | protected NutrientTable getNutrientTable() {
38 | if (nutrientTable == null) {
39 | nutrientTable = new NutrientTable(NutrientInfo.getMacroNutrients());
40 | }
41 | return nutrientTable;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/MineralSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.BorderLayout;
4 | import java.util.List;
5 |
6 | import javax.swing.BorderFactory;
7 |
8 | import ca.spaz.cron.foods.NutrientInfo;
9 |
10 | public class MineralSummaryPanel extends AbstractNutrientSummaryPanel {
11 |
12 | public MineralSummaryPanel() {
13 | setLayout(new BorderLayout());
14 | setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
15 | add(getNutrientTablePane(), BorderLayout.CENTER);
16 | }
17 |
18 | protected List getNutrientList() {
19 | return NutrientInfo.getMinerals();
20 | }
21 |
22 | protected String getCategoryName() {
23 | return "Minerals";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/SummaryFormat.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.text.DateFormat;
4 | import java.text.DecimalFormat;
5 | import java.util.*;
6 |
7 | import ca.spaz.cron.foods.NutrientInfo;
8 | import ca.spaz.cron.foods.Serving;
9 | import ca.spaz.cron.targets.Target;
10 | import ca.spaz.cron.user.UserManager;
11 |
12 | public abstract class SummaryFormat {
13 | protected DecimalFormat df = new DecimalFormat("######0.0");
14 | protected DecimalFormat nf = new DecimalFormat("######0%");
15 | protected DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
16 |
17 | public abstract String getFormatName();
18 |
19 | public String toString() {
20 | return getFormatName();
21 | }
22 |
23 | public abstract String export(List servings, Date start, Date end, int days, boolean targetsOnly);
24 | public abstract String exportCategory(String category, List servings, int days, boolean targetsOnly);
25 | public abstract String export(NutrientInfo ni, List servings, int days, boolean targetsOnly);
26 |
27 | public double getAmount(List servings, NutrientInfo ni) {
28 | double total = 0;
29 | for (Iterator iter = servings.iterator(); iter.hasNext(); ) {
30 | Serving serving = (Serving) iter.next();
31 | double weight = serving.getGrams() / 100.0;
32 | total += weight * serving.getFood().getNutrientAmount(ni);
33 | }
34 | return total;
35 | }
36 |
37 | /**
38 | * Look through all nutrients and see what overall percentage of the targets
39 | * are completed.
40 | */
41 | public double getTargetCompletion(List servings, List nutrients, int days, boolean average) {
42 | double total = 0;
43 | double value = 0;
44 | double valueFull = 0;
45 |
46 | Iterator iter = nutrients.iterator();
47 | while (iter.hasNext()) {
48 | NutrientInfo ni = (NutrientInfo)iter.next();
49 | Target target = UserManager.getCurrentUser().getTarget(ni);
50 | if (target.getMin() > 0 && UserManager.getCurrentUser().isTracking(ni)) {
51 | double amount = getAmount(servings, ni) / (double) days;
52 | valueFull += amount / target.getMin();
53 | if (amount < target.getMin()) {
54 | value += amount / target.getMin();
55 | } else {
56 | value++;
57 | }
58 | total++;
59 | }
60 | }
61 | if (average) {
62 | return valueFull / total;
63 | } else {
64 | return value / total;
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/summary/VitaminSummaryPanel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.summary;
2 |
3 | import java.awt.BorderLayout;
4 | import java.util.List;
5 |
6 | import javax.swing.BorderFactory;
7 |
8 | import ca.spaz.cron.foods.NutrientInfo;
9 |
10 | public class VitaminSummaryPanel extends AbstractNutrientSummaryPanel {
11 |
12 | public VitaminSummaryPanel() {
13 | setLayout(new BorderLayout());
14 | setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
15 | add(getNutrientTablePane(), BorderLayout.CENTER);
16 | }
17 |
18 | protected List getNutrientList() {
19 | return NutrientInfo.getVitamins();
20 | }
21 |
22 | protected String getCategoryName() {
23 | return "Vitamins";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/targets/Target.java:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * Copyright (c) 2005 Chris Rose and AIMedia
4 | * All rights reserved. Target and the accompanying materials
5 | * are made available under the terms of the Common Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/cpl-v10.html
8 | *
9 | * Contributors:
10 | * Chris Rose
11 | *******************************************************************************/
12 | package ca.spaz.cron.targets;
13 |
14 | public class Target {
15 | double min, max;
16 |
17 | public Target() {
18 | }
19 |
20 | public Target(double min, double max) {
21 | this.min = min;
22 | this.max = max;
23 | }
24 |
25 | public double getMax() {
26 | return max;
27 | }
28 |
29 | public void setMax(double max) {
30 | this.max = max;
31 | }
32 |
33 | public double getMin() {
34 | return min;
35 | }
36 |
37 | public void setMin(double min) {
38 | this.min = min;
39 | }
40 |
41 | public boolean isUndefined() {
42 | return min <= 0 && max <= 0;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/targets/TargetEditorTable.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.targets;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.util.List;
6 |
7 | import javax.swing.*;
8 | import javax.swing.table.TableColumn;
9 |
10 | import ca.spaz.cron.user.User;
11 | import ca.spaz.gui.PrettyTable;
12 |
13 | /**
14 | * @author Aaron Davidson
15 | */
16 | public class TargetEditorTable extends JScrollPane {
17 |
18 | TargetEditorTableModel model;
19 | PrettyTable nutrientTable;
20 |
21 | public TargetEditorTable(User user, List nutrients) {
22 | model = new TargetEditorTableModel(user, nutrients);
23 | setViewportView(getTable());
24 | getViewport().setBackground(Color.WHITE);
25 | setPreferredSize(new Dimension(350, 200));
26 | }
27 |
28 | private JTable getTable() {
29 | if (null == nutrientTable) {
30 | nutrientTable = new PrettyTable(model);
31 | nutrientTable.getSelectionModel().setSelectionMode(
32 | ListSelectionModel.SINGLE_SELECTION);
33 | nutrientTable.getTableHeader().setReorderingAllowed(false);
34 | for (int i = 0; i < model.getColumnCount(); i++) {
35 | TableColumn tc = nutrientTable.getTableHeader().getColumnModel().getColumn(i);
36 | tc.setPreferredWidth(model.getColumnMaxWidth(i));
37 | }
38 | }
39 | return nutrientTable;
40 | }
41 |
42 | public void fireTargetsChanged() {
43 | model.fireTableDataChanged();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/targets/TargetModel.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.targets;
2 |
3 | import ca.spaz.cron.foods.NutrientInfo;
4 | import ca.spaz.cron.user.User;
5 |
6 | /**
7 | * A Target Model can suggest targets for a User
8 | *
9 | * This lets us add different expert systems that
10 | * suggest nutrient target values for a user,
11 | * based on their parameters (age, weight, sex, etc...)
12 | *
13 | * @author Aaron Davidson
14 | */
15 | public interface TargetModel {
16 |
17 | public double getTargetMinimum(User user, NutrientInfo ni);
18 | public double getTargetMaximum(User user, NutrientInfo ni);
19 | }
20 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/ui/ReadMe.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.ui;
2 |
3 | import java.awt.BorderLayout;
4 | import java.awt.Dimension;
5 | import java.net.URL;
6 |
7 | import javax.swing.ImageIcon;
8 | import javax.swing.JFrame;
9 |
10 | import ca.spaz.gui.*;
11 |
12 | public class ReadMe extends WrappedPanel {
13 | private String title;
14 |
15 | public ReadMe(JFrame parent, String title, URL url) {
16 | this.title = title;
17 | setLayout(new BorderLayout());
18 | WebViewer wv = new WebViewer(url);
19 | wv.setPreferredSize(new Dimension(600, 400));
20 | add(wv, BorderLayout.CENTER);
21 | WrapperDialog.showDialog(parent, this);
22 | }
23 |
24 | public String getTitle() {
25 | return title;
26 | }
27 |
28 | public String getSubtitle() {
29 | return title;
30 | }
31 |
32 | public String getInfoString() {
33 | return null;
34 | }
35 |
36 | public ImageIcon getIcon() {
37 | return null;
38 | }
39 |
40 | public boolean showSidebar() {
41 | return false;
42 | }
43 |
44 | public boolean isCancellable() {
45 | return false;
46 | }
47 |
48 | public void doCancel() {
49 | }
50 |
51 | public boolean doAccept() {
52 | return true;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/ui/SearchHit.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.ui;
2 |
3 | import ca.spaz.cron.datasource.Datasources;
4 | import ca.spaz.cron.datasource.FoodProxy;
5 |
6 |
7 | public class SearchHit implements Comparable {
8 | private FoodProxy fp;
9 | private int score;
10 |
11 | public SearchHit(FoodProxy fp) {
12 | this.fp = fp;
13 | }
14 |
15 | /**
16 | * A heuristic scoring function to give a smart sort of the results
17 | * @param query the user's search terms, as entered
18 | */
19 | public void computeScore(String[] query) {
20 | score = 100; // base score, so we don't go negative
21 |
22 | // start off with big bonus for having a history of being used
23 | score += fp.getReferences() * 100;
24 |
25 | // I hate how USDA is full of babyfoods. Come on, really.
26 | if (fp.getDescription().startsWith("Babyfood")) {
27 | score -= 100;
28 | }
29 |
30 | if (fp.getSource() == Datasources.getUserFoods()) {
31 | score += 100;
32 | } else if (fp.getSource() == Datasources.getCRDBFoods()) {
33 | score += 50;
34 | }
35 |
36 | // penalize longer strings. We're usually searching for short, simple foods.
37 | score -= 3 * getFoodProxy().getDescription().length();
38 |
39 | // add bonus for search terms being early in the description
40 | for (int i = 0; i < query.length; i++) {
41 | score += 50 * (1.0 - (fp.getDescription().indexOf(query[i]) / (double)fp.getDescription().length()));
42 | }
43 |
44 | if (fp.isDeprecated()) {
45 | score -= 200;
46 | }
47 |
48 | }
49 |
50 | public int getScore() {
51 | return score;
52 | }
53 | public FoodProxy getFoodProxy() {
54 | return fp;
55 | }
56 |
57 | public int compareTo(Object obj) {
58 | SearchHit hit = (SearchHit) obj;
59 |
60 | if (getScore() > hit.getScore()) {
61 | return -1;
62 | }
63 | if (getScore() < hit.getScore()) {
64 | return 1;
65 | }
66 |
67 | // break tie with alphabetical order
68 | return getFoodProxy().getDescription().compareToIgnoreCase(hit.getFoodProxy().getDescription());
69 | }
70 |
71 | public int compareByName(Object obj) {
72 | SearchHit hit = (SearchHit) obj;
73 | return getFoodProxy().getDescription().compareToIgnoreCase(hit.getFoodProxy().getDescription());
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/user/Favorites.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.cron.user;
2 |
3 |
4 | public class Favorites {
5 | private static final int MAX_SLOTS = 1000;
6 |
7 | public class Favorite implements Comparable {
8 | Object val;
9 | int rank;
10 |
11 | public int compareTo(Object arg0) {
12 | return 0;
13 | }
14 | }
15 |
16 | private Favorite[] favorites = new Favorite[MAX_SLOTS];
17 | }
18 |
--------------------------------------------------------------------------------
/src/ca/spaz/cron/user/UserChangeListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * Copyright (c) 2005 Chris Rose and AIMedia
4 | * All rights reserved. UserChangeListener and the accompanying materials
5 | * are made available under the terms of the Common Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/cpl-v10.html
8 | *
9 | * Contributors:
10 | * Chris Rose
11 | *******************************************************************************/
12 | package ca.spaz.cron.user;
13 |
14 | /**
15 | * An interface to be implemented by objects interested in user model changes.
16 | * @author Chris Rose
17 | */
18 | public interface UserChangeListener {
19 |
20 | /**
21 | * This event is fired whenever the user model changes in some way.
22 | * @param userMan the User
that has changed.
23 | */
24 | void userChanged(UserManager userMan);
25 | }
26 |
--------------------------------------------------------------------------------
/src/ca/spaz/gui/DateChooser.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.gui;
2 |
3 | import java.util.Date;
4 |
5 | import javax.swing.ImageIcon;
6 | import javax.swing.JComponent;
7 |
8 | import org.jdesktop.swingx.JXMonthView;
9 |
10 |
11 | public class DateChooser extends WrappedPanel {
12 | private String title = "Choose Date";
13 |
14 | private JXMonthView cal;
15 |
16 | public DateChooser(Date curDate) {
17 | cal = new JXMonthView();
18 | cal.setTraversable(true);
19 | cal.setSelectionInterval(curDate, curDate);
20 |
21 | add(cal);
22 | }
23 |
24 | public static Date pickDate(JComponent parent, Date d) {
25 | DateChooser dc = new DateChooser(d);
26 | WrapperDialog.showDialog(parent, dc);
27 | return dc.cal.getSelection().first();
28 | }
29 |
30 | public static Date pickDate(JComponent parent, Date d, String title) {
31 | DateChooser dc = new DateChooser(d);
32 | dc.setTitle(title);
33 | WrapperDialog.showDialog(parent, dc);
34 | return dc.cal.getSelection().first();
35 | }
36 |
37 | private void setTitle(String title) {
38 | this.title = title;
39 | }
40 |
41 | public String getTitle() {
42 | return title;
43 | }
44 |
45 | public String getSubtitle() {
46 | return null;
47 | }
48 |
49 | public String getInfoString() {
50 | return title;
51 | }
52 |
53 | public ImageIcon getIcon() {
54 | return null;
55 | }
56 |
57 | public boolean showSidebar() {
58 | return false;
59 | }
60 |
61 | public boolean isCancellable() {
62 | return false;
63 | }
64 |
65 | public void doCancel() {
66 | }
67 |
68 | public boolean doAccept() {
69 | return true;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/ca/spaz/gui/DoubleField.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.gui;
2 |
3 | import java.awt.Toolkit;
4 | import java.text.DecimalFormat;
5 |
6 | import javax.swing.JTextField;
7 | import javax.swing.text.*;
8 |
9 | import ca.spaz.util.ToolBox;
10 |
11 | /**
12 | * A text field for entering floating point data. The only characters it accepts
13 | * are the digits 0-9 and one (optional) decimal point.
14 | *
15 | * @author Aaron
16 | *
17 | */
18 | public class DoubleField extends JTextField {
19 | private Toolkit toolkit;
20 |
21 | private double min = Integer.MIN_VALUE, max = Integer.MAX_VALUE;
22 |
23 | private DecimalFormat df = new DecimalFormat("#########0.0###");
24 |
25 | public DoubleField(double value, int columns) {
26 | super(columns);
27 | setHorizontalAlignment(JTextField.RIGHT);
28 | toolkit = Toolkit.getDefaultToolkit();
29 | setValue(value);
30 | }
31 |
32 | public void setRange(double min, double max) {
33 | this.min = min;
34 | this.max = max;
35 | }
36 |
37 | public double getValue() {
38 | double retVal = 0.0;
39 | String[] q;
40 | double[] r = {0.0, 0.0};
41 | q = getText().split("/", 2);
42 | try {
43 | for (int i = 0; i < q.length; i++) {
44 | r[i] = Double.parseDouble(q[i]);
45 | }
46 | } catch (NumberFormatException e) {
47 | }
48 | retVal = ToolBox.safeDivide(r[0], r[1], r[0]);
49 | if (retVal < min) {
50 | retVal = min;
51 | }
52 | if (retVal > max) {
53 | retVal = max;
54 | }
55 | return retVal;
56 | }
57 |
58 | public void setValue(double value) {
59 | if (value < min) {
60 | value = min;
61 | }
62 | if (value > max) {
63 | value = max;
64 | }
65 | if (value == 0.0) {
66 | setText("");
67 | } else {
68 | setText(df.format(value));
69 | }
70 | selectAll();
71 | }
72 |
73 | public void setValue(String value) {
74 | setText(value);
75 | }
76 |
77 | protected Document createDefaultModel() {
78 | return new DoubleDocument();
79 | }
80 |
81 | protected String getCurrentText() {
82 | return getText();
83 | }
84 |
85 | protected class DoubleDocument extends PlainDocument {
86 | // Overridden to allow only digits and one decimal point e.g. 1.00
87 | // Note that not all data that would allowed by Double.parseDouble() is
88 | // supported, e.g.
89 | // exponential notation, negative signs, hex notation etc.
90 | public void insertString(int offs, String str, AttributeSet a)
91 | throws BadLocationException {
92 | char[] source = str.toCharArray();
93 | char[] result = new char[source.length];
94 | int j = 0;
95 | for (int i = 0; i < result.length; i++) {
96 | char c = source[i];
97 | if (Character.isDigit(c)
98 | || (c == '.' && getCurrentText().indexOf('.') == -1)
99 | || (c == '/' && getCurrentText().indexOf('/') == -1)) {
100 | result[j++] = c;
101 | } else {
102 | toolkit.beep();
103 | }
104 | }
105 | super.insertString(offs, new String(result, 0, j), a);
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/ca/spaz/gui/ErrorReporter.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.gui;
2 |
3 | import java.awt.BorderLayout;
4 | import java.awt.Component;
5 |
6 | import javax.swing.*;
7 |
8 | import ca.spaz.util.ImageFactory;
9 |
10 | public class ErrorReporter extends WrappedPanel {
11 | private String message;
12 |
13 | public ErrorReporter(Exception e) {
14 | StringBuffer sb = new StringBuffer();
15 | if (e != null) {
16 | sb.append("");
19 | for (int i = 0; i < e.getStackTrace().length && i < 8; i++) {
20 | sb.append(e.getStackTrace()[i].toString() + "
");
21 | }
22 | sb.append("
cols
from the SQLInsert
61 | * @return Returns the cols.
62 | */
63 | public SQLColumnSet getColumns() {
64 | return cols;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/ca/spaz/sql/SQLRow.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.sql;
2 |
3 | import java.sql.*;
4 | import java.util.HashMap;
5 | import java.util.Iterator;
6 |
7 | /**
8 | * @TODO: rename, enhance.
9 | *
10 | * A super-simple relational-object mapping system.
11 | *
12 | * @author adavidson
13 | */
14 | public class SQLRow {
15 | private String name;
16 | private HashMap rows = new HashMap();
17 |
18 | public class SQLCol {
19 | int type;
20 | String name;
21 | Object value;
22 | }
23 |
24 | public SQLRow(String name) {
25 | this.name = name;
26 | }
27 |
28 | public void addColumn(String name, int type) {
29 | SQLCol col = new SQLCol();
30 | col.type = type;
31 | col.name = name;
32 | rows.put(name, col);
33 | }
34 |
35 | public void setValue(String name, Object val) {
36 | SQLCol col = (SQLCol)rows.get(name);
37 | assert (col != null);
38 | if (col != null) {
39 | col.value = val;
40 | }
41 | }
42 |
43 | private String getDatabaseTypeName(int colType) {
44 | switch (colType) {
45 | case Types.TINYINT: {
46 | return "TINYINT";
47 | }
48 | case Types.SMALLINT: {
49 | return "SMALLINT";
50 | }
51 | case Types.INTEGER: {
52 | return "INTEGER";
53 | }
54 | case Types.BIGINT: {
55 | return "BIGINT";
56 | }
57 | case Types.VARCHAR: {
58 | return "VARCHAR";
59 | }
60 | case Types.TIMESTAMP: {
61 | return "TIMESTAMP";
62 | }
63 | case Types.DOUBLE: {
64 | return "DOUBLE";
65 | }
66 | default: {
67 | return null;
68 | }
69 | }
70 | }
71 |
72 | public void createTable(Connection conn) throws SQLException {
73 | StringBuffer sql = new StringBuffer();
74 |
75 | sql.append("CREATE TABLE ");
76 | sql.append(name);
77 | sql.append(" ( ");
78 |
79 | int count = 0;
80 | Iterator iter = rows.values().iterator();
81 | while (iter.hasNext()) {
82 | SQLCol col = (SQLCol) iter.next();
83 | sql.append(col.name);
84 | sql.append(" ");
85 | sql.append(getDatabaseTypeName(col.type));
86 | if (++count < rows.size()) {
87 | sql.append(", ");
88 | }
89 | }
90 | sql.append(" ); ");
91 |
92 | conn.createStatement().execute(sql.toString());
93 |
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/ca/spaz/sql/SQLStatement.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.sql;
2 |
3 | import java.sql.*;
4 |
5 | /**
6 | * Base class for SQL command generators
7 | *
8 | * @author davidson
9 | */
10 | public abstract class SQLStatement {
11 |
12 | public final void execute(Connection con) throws SQLException {
13 | if (!isExecuteSupported()) {
14 | throw new UnsupportedOperationException("Execute not supported on "
15 | + getClass().getName());
16 | }
17 | doExecute(con);
18 | }
19 |
20 | protected void doExecute(Connection con) throws SQLException {
21 | }
22 |
23 | public final boolean isExecuteSupported() {
24 | return executeSupport;
25 | }
26 |
27 | public final ResultSet executeQuery(Connection con) throws SQLException {
28 | if (!isQuerySupported()) {
29 | throw new UnsupportedOperationException("Query not supported on "
30 | + getClass().getName());
31 | }
32 | return doExecuteQuery(con);
33 | }
34 |
35 | protected ResultSet doExecuteQuery(Connection con) throws SQLException {
36 | return null;
37 | }
38 |
39 | public final boolean isQuerySupported() {
40 | return querySupport;
41 | }
42 |
43 | protected String table;
44 |
45 | private boolean querySupport;
46 |
47 | private boolean executeSupport;
48 |
49 | protected SQLStatement(String table, boolean querySupport,
50 | boolean executeSupport) {
51 | this.table = table;
52 | this.querySupport = querySupport;
53 | this.executeSupport = executeSupport;
54 | }
55 |
56 | public String getTableName() {
57 | return table;
58 | }
59 |
60 | public static String escape(String s) {
61 | return s.replaceAll("\\'", "\\'\\'");
62 | }
63 |
64 | protected abstract String getQueryString();
65 |
66 | public String toString() {
67 | return getQueryString();
68 | }
69 |
70 | /**
71 | * Ensure that correct classes (with respect to toString()) ge
72 | * passed on
73 | * @param o the class to check.
74 | * @return a valid class for SQL
75 | */
76 | static Object fixClass(Object o) {
77 | if (o instanceof java.util.Date) {
78 | o = new java.sql.Date(((java.util.Date)o).getTime());
79 | }
80 | return o;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/ca/spaz/sql/SQLUpdate.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.sql;
2 |
3 | import java.sql.*;
4 | import java.util.List;
5 |
6 | import ca.spaz.util.Logger;
7 |
8 | /**
9 | * Simplifies constructing SQL Update Queries.
10 | */
11 | public class SQLUpdate extends SQLSelectableStatement implements Columns {
12 |
13 | private SQLColumnSet cols;
14 |
15 | /**
16 | * Create a new SQLUpdate command for the given table
17 | * @param tableName the name of the table to update on
18 | */
19 | public SQLUpdate(String tableName) {
20 | super(tableName, true, false, true);
21 | cols = new SQLColumnSet();
22 | }
23 |
24 | /**
25 | * Overrides execute() and calls executeUpdate()
26 | */
27 | protected void doExecute(Connection con) throws SQLException {
28 | Statement stmt = con.createStatement();
29 | String query = this.getQueryString();
30 | if (Logger.isDebugEnabled()) {
31 | Logger.debug("executeQuery() - Statement to be executed: " + query);
32 | }
33 |
34 | stmt.executeUpdate(query);
35 | }
36 |
37 | /**
38 | * Generate the SQL string for an UPDATE command.
39 | */
40 | protected String getQueryString() {
41 | StringBuffer sb = new StringBuffer();
42 | sb.append("UPDATE ");
43 | sb.append(getTableName());
44 | sb.append(" SET ");
45 | List names = cols.getNames();
46 | List terms = cols.getValues();
47 | for (int i = 0; i < names.size(); i++) {
48 | Object name = names.get(i);
49 | Object term = terms.get(i);
50 | if (term == null) {
51 | term = "NULL";
52 | }
53 | sb.append(name.toString());
54 | sb.append(" = '");
55 | sb.append(escape(term.toString()));
56 | sb.append("' ");
57 | if (i < names.size() - 1) {
58 | sb.append(", ");
59 | }
60 | }
61 | sb.append(getWhere());
62 | return sb.toString();
63 | }
64 |
65 | /**
66 | * Retrieve the cols
from the SQLInsert
67 | * @return Returns the cols.
68 | */
69 | public SQLColumnSet getColumns() {
70 | return cols;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/ca/spaz/task/Task.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.task;
2 |
3 | public interface Task extends Runnable {
4 |
5 | /**
6 | * A number between 0 and 100 representing the
7 | * % completion of the task.
8 | *
9 | * @return the percentage complete
10 | */
11 | public int getTaskProgress();
12 |
13 | /**
14 | * The task has been cancelled. Attempt to stop.
15 | */
16 | public void abortTask();
17 |
18 | /**
19 | * Return true if the program can finish.
20 | *
21 | * @return true if the task can be aborted.
22 | */
23 | public boolean canAbortTask();
24 |
25 | /**
26 | * A description of the current Task being performed
27 | *
28 | * @return the description of the current Task being performed
29 | */
30 | public String getTaskDescription();
31 | }
32 |
--------------------------------------------------------------------------------
/src/ca/spaz/task/TaskListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.task;
2 |
3 | public interface TaskListener {
4 |
5 | public void taskStarted(Task t);
6 | public void taskFinished(Task t);
7 | public void taskAborted(Task t);
8 | }
9 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/CountableInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * Copyright (c) 2005 Chris Rose and AIMedia
4 | * All rights reserved. CountableBufferedInputStream and the accompanying materials
5 | * are made available under the terms of the Common Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/cpl-v10.html
8 | *
9 | * Contributors:
10 | * Chris Rose
11 | *******************************************************************************/
12 | package ca.spaz.util;
13 |
14 | import java.io.*;
15 |
16 | /**
17 | * This class implements an InputStream that counts the bytes that it has
18 | * read.
19 | *
20 | * @author Chris Rose
21 | */
22 | public class CountableInputStream extends FilterInputStream {
23 |
24 | private long bytesRetrieved = 0;
25 |
26 | private long markpos = -1;
27 |
28 | /**
29 | * Create a new CountableInputStream
and wrap it around the
30 | * supplied InputStream
.
31 | *
32 | * @param in an InputStream
object to count.
33 | */
34 | public CountableInputStream(InputStream in) {
35 | super(in);
36 | }
37 |
38 | /* (non-Javadoc)
39 | * @see java.io.InputStream#read()
40 | */
41 | public synchronized int read() throws IOException {
42 | int next = super.read();
43 | if (next != -1) {
44 | bytesRetrieved++;
45 | }
46 | return next;
47 | }
48 |
49 | /* (non-Javadoc)
50 | * @see java.io.InputStream#read(byte[], int, int)
51 | */
52 | public synchronized int read(byte[] b, int off, int len) throws IOException {
53 | int next = super.read(b, off, len);
54 | if (next != -1) {
55 | bytesRetrieved += next;
56 | }
57 | return next;
58 | }
59 |
60 | /* (non-Javadoc)
61 | * @see java.io.InputStream#mark(int)
62 | */
63 | public synchronized void mark(int readlimit) {
64 | super.mark(readlimit);
65 | markpos = bytesRetrieved;
66 | }
67 |
68 | /* (non-Javadoc)
69 | * @see java.io.InputStream#skip(long)
70 | */
71 | public long skip(long n) throws IOException {
72 | long next = super.skip(n);
73 | bytesRetrieved += next;
74 | return next;
75 | }
76 |
77 | /* (non-Javadoc)
78 | * @see java.io.InputStream#reset()
79 | */
80 | public synchronized void reset() throws IOException {
81 | bytesRetrieved = markpos;
82 | super.reset();
83 | }
84 |
85 | /* (non-Javadoc)
86 | * @see java.io.InputStream#read(byte[])
87 | */
88 | public int read(byte[] b) throws IOException {
89 | int next = super.read(b);
90 | if (next != -1) {
91 | bytesRetrieved += next;
92 | }
93 | return next;
94 | }
95 |
96 | /**
97 | * Get a count of the bytes read by this stream.
98 | * @return the number of bytes read by this stream.
99 | */
100 | public long getBytesRead() {
101 | return bytesRetrieved;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/ImageFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * Copyright (c) 2005 Chris Rose and AIMedia
4 | * All rights reserved. ImageFactory and the accompanying materials
5 | * are made available under the terms of the Common Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/cpl-v10.html
8 | *
9 | * Contributors:
10 | * Chris Rose
11 | *******************************************************************************/
12 | package ca.spaz.util;
13 |
14 | import java.awt.Image;
15 | import java.awt.Toolkit;
16 | import java.net.URL;
17 | import java.util.Map;
18 |
19 | /**
20 | * A class for manufacturing images from the resource path.
21 | * @author Chris Rose
22 | */
23 | public class ImageFactory {
24 |
25 | private static ImageFactory instance = null;
26 | private int cacheSize;
27 | private Map imageCache;
28 |
29 | private ImageFactory(int cacheSz) {
30 | this.cacheSize = cacheSz;
31 | this.imageCache = new CacheMap(cacheSize);
32 | }
33 |
34 | public static final ImageFactory getInstance() {
35 | if (null == instance) {
36 | instance = new ImageFactory(10);
37 | }
38 | return instance;
39 | }
40 |
41 | public Image loadImage(URL url) {
42 | Image ret = null;
43 | if (imageCache.containsKey(url)) {
44 | ret = (Image) imageCache.get(url);
45 | } else {
46 | ret = Toolkit.getDefaultToolkit().createImage(url);
47 | if (ret != null) {
48 | imageCache.put(url, ret);
49 | }
50 | }
51 | return ret;
52 | }
53 |
54 | public Image loadImage(String resourceID) {
55 | return loadImage(resourceID, this);
56 | }
57 |
58 | public Image loadImage(String resourceID, Object source) {
59 | Class base = null;
60 | if (null == source) {
61 | base = this.getClass();
62 | } else {
63 | base = source.getClass();
64 | }
65 | URL url = base.getResource(resourceID);
66 | Image ret = null;
67 | if (url == null) {
68 | url = this.getClass().getResource(resourceID);
69 | if (url == null) {
70 | throw new IllegalArgumentException(resourceID + " is not a valid resource identifier");
71 | }
72 | }
73 | ret = loadImage(url);
74 | return ret;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/JarLoader.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.util;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.net.*;
6 |
7 | /**
8 | * Allows class resources to be accessed by URL stream type.
9 | */
10 | public class JarLoader extends URLStreamHandler implements URLStreamHandlerFactory {
11 |
12 | public URLStreamHandler createURLStreamHandler(String protocol) {
13 | return (protocol.equalsIgnoreCase("class")) ? this : null;
14 | }
15 |
16 | protected URLConnection openConnection(final URL url) throws IOException {
17 | return new URLConnection(url) {
18 | private Class base;
19 |
20 | public synchronized void connect() throws IOException {
21 | if (base == null) {
22 | try {
23 | base = Class.forName(url.getHost());
24 | } catch (ClassNotFoundException e) {
25 | throw new IOException(e.getLocalizedMessage());
26 | }
27 | }
28 | }
29 |
30 | public synchronized InputStream getInputStream() throws IOException {
31 | connect(); // make sure we're connected
32 | String path = url.getPath();
33 | if (path.startsWith("/")) {
34 | path = path.substring(1);
35 | }
36 | return base.getClassLoader().getResourceAsStream(path);
37 | }
38 |
39 | public String getContentType() {
40 | return guessContentTypeFromName(url.getPath());
41 | }
42 |
43 | };
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/Logger.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.util;
2 |
3 | public class Logger {
4 |
5 | public static void log(String str) {
6 | System.out.println(str);
7 | }
8 |
9 | public static void debug(String str) {
10 | System.out.println(str);
11 | }
12 |
13 | public static void error(Exception e) {
14 | e.printStackTrace();
15 | }
16 |
17 | public static void debug(Exception e) {
18 | e.printStackTrace();
19 | }
20 |
21 | public static void error(String str) {
22 | System.err.println(str);
23 | }
24 |
25 | public static void error(String str, Exception e) {
26 | System.err.println(str);
27 | e.printStackTrace();
28 | }
29 |
30 | public static boolean isDebugEnabled() {
31 | return true;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/ProgressListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * Copyright (c) 2005 Chris Rose and AIMedia
4 | * All rights reserved. ProgressListener and the accompanying materials
5 | * are made available under the terms of the Common Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/cpl-v10.html
8 | *
9 | * Contributors:
10 | * Chris Rose
11 | *******************************************************************************/
12 | package ca.spaz.util;
13 |
14 | /**
15 | * This interface should be implemented by classes interested in being informed of the
16 | * progress of some other thread.
17 | *
18 | * @author Chris Rose
19 | */
20 | public interface ProgressListener {
21 |
22 | /**
23 | * This event is fired when the progress item being tracked starts.
24 | */
25 | void progressStart();
26 |
27 | /**
28 | * This event is fired when the progress item being tracked finishes. At this point,
29 | * the item's progress should be considered to be 100%
30 | */
31 | void progressFinish();
32 |
33 | /**
34 | * This event is fired whenever the progress item being tracked updates its public
35 | * progress level.
36 | *
37 | * @param percent A number from 0 to 100 indicating the progress of the tracked item.
38 | */
39 | void progress(int percent);
40 | }
41 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/SettingsChangeEvent.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.util;
2 |
3 | import java.util.EventObject;
4 |
5 | public class SettingsChangeEvent extends EventObject {
6 |
7 | private String key;
8 | private String newValue;
9 |
10 | public SettingsChangeEvent(Object source, String key, String val) {
11 | super(source);
12 | this.key = key;
13 | this.newValue = val;
14 | }
15 |
16 | /**
17 | * Returns the key of the setting that was changed.
18 | *
19 | * @return The key of the setting that was changed.
20 | */
21 | public String getKey() {
22 | return key;
23 | }
24 |
25 | /**
26 | * Returns the new value for the setting.
27 | *
28 | * @return The new value for the setting, or null if the
29 | * setting was removed.
30 | */
31 | public String getNewValue() {
32 | return newValue;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/ca/spaz/util/SettingsChangeListener.java:
--------------------------------------------------------------------------------
1 | package ca.spaz.util;
2 |
3 | public interface SettingsChangeListener extends java.util.EventListener {
4 | /**
5 | * This method gets called when a setting is added, removed or when
6 | * its value is changed.
7 | * 8 | * @param evt A SettingsChangeEvent object describing the event source 9 | * and the setting that has changed. 10 | */ 11 | void settingChange(SettingsChangeEvent evt); 12 | } 13 | -------------------------------------------------------------------------------- /src/ca/spaz/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package ca.spaz.util; 2 | 3 | public class StringUtil { 4 | public static final int PAD_LEFT = 0; 5 | public static final int PAD_RIGHT = 1; 6 | public static final int PAD_CENTER = 2; 7 | 8 | public static String padr(String str, int num) { 9 | return pad(str, num, PAD_RIGHT, ' '); 10 | } 11 | 12 | public static String padl(String str, int num) { 13 | return pad(str, num, PAD_LEFT, ' '); 14 | } 15 | 16 | public static String padc(String str, int num) { 17 | return pad(str, num, PAD_CENTER, ' '); 18 | } 19 | 20 | public static String pad(String str, int num, int side, char pad) { 21 | int len = str.length(); 22 | if (len >= num) { 23 | return str; 24 | } 25 | StringBuffer sb = new StringBuffer(); 26 | switch (side) { 27 | case PAD_LEFT: 28 | while (len++ < num) { 29 | sb.append(pad); 30 | } 31 | sb.append(str); 32 | break; 33 | case PAD_RIGHT: 34 | sb.append(str); 35 | while (len++ < num) { 36 | sb.append(pad); 37 | } 38 | break; 39 | case PAD_CENTER: 40 | int n = (num - len) / 2; 41 | while (n-- >= 0) { 42 | sb.append(pad); 43 | } 44 | sb.append(str); 45 | while (len++ < num) { 46 | sb.append(pad); 47 | } 48 | break; 49 | } 50 | return sb.toString(); 51 | } 52 | 53 | public static String charRun(char c, int i) { 54 | StringBuffer sb = new StringBuffer(); 55 | while (i-- >= 0) { 56 | sb.append(c); 57 | } 58 | return sb.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/ca/spaz/wizard/WizardPanel.java: -------------------------------------------------------------------------------- 1 | package ca.spaz.wizard; 2 | 3 | import javax.swing.JPanel; 4 | 5 | public abstract class WizardPanel extends JPanel { 6 | private Wizard controller; 7 | 8 | public abstract String getWizardPanelTitle(); 9 | 10 | public abstract void commitChanges(); 11 | 12 | /** 13 | * @return true if the wizard panel is completed and user input is valid 14 | * The Wizard will not allow proceeding to next pane unless the current 15 | * pane returns isValid. 16 | */ 17 | public abstract boolean isValid(); 18 | 19 | 20 | protected void setWizard(Wizard w) { 21 | this.controller = w; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/com/apple/mrj/MRJAboutHandler.java: -------------------------------------------------------------------------------- 1 | package com.apple.mrj; 2 | /** 3 | * A stub for the windows build. This class is loaded under windows 4 | * and apple's real class is loaded instead on Mac OS X. 5 | * 6 | * @author Aaron Davidson 7 | */ 8 | public interface MRJAboutHandler { 9 | public void handleAbout(); 10 | } 11 | -------------------------------------------------------------------------------- /src/com/apple/mrj/MRJQuitHandler.java: -------------------------------------------------------------------------------- 1 | package com.apple.mrj; 2 | /** 3 | * A stub for the windows build. This class is loaded under windows 4 | * and apple's real class is loaded instead on Mac OS X. 5 | * 6 | * @author Aaron Davidson 7 | */ 8 | public interface MRJQuitHandler { 9 | public void handleQuit(); 10 | } 11 | -------------------------------------------------------------------------------- /src/docs/issues.html: -------------------------------------------------------------------------------- 1 | This is a scratch page right now for important nuances and issues that should be discussed in the user manual. 2 | 3 | ---- 4 | 5 | 6 | Not all nutrients in database are 'complete'. Some nutrients are under-represented in the 7 | USDA data-set, so it may appear as if you are deficient in those particular nutrients when 8 | the case is that any foods are simply lacking any information for those nutrients. 9 | 10 | * Am I deficient or is the Database? 11 | 12 | Vitamin D, for instance, is heavily underrepresented. It's high in many fishes like 13 | tuna and salmon, but most USDA entries on salmon and tuna lack information for Vitamin D. 14 | 15 | ---- 16 | 17 | Discuss all the hidden features like keyboard shortcuts, pop-up menus, etc... 18 | 19 | ---- 20 | 21 | Hidden feature: Multiple profiles 22 | 23 | If you pass it a single command line argument, it will create/load under a new account by that name. For example: 24 | 25 | ./Cronometer.exe Jon1 26 | 27 | Would load up the 'Jon1' profile instead of the default. 28 | 29 | Note: It doesn't currently show the name anywhere, so you'd have to handle that detail yourself for the time being. 30 | ---- 31 | 32 | USDA sr19 deprecated some foods from USDAsr18. The foods have been kept for 33 | backwards compatibility, but it is recommend you no longer use them. They will 34 | show up as light grey in the search and food listings. These items were removed 35 | because either the nutritional data is considered out of date and/or the product 36 | is no longer available on the market. 37 | 38 | 39 | ---- 40 | 41 | Scientific Tasks 42 | 43 | -- Read *carefully* through the USDA documentation and compile a list of important issues to consider 44 | -- find out which data may be unreliable and what nutrients are systematically underrepresented in the data 45 | 46 | -- Read carefully through DRIs for issues 47 | -- double check the values in nutrients.xml for mistakes 48 | -- add missing data 49 | -- double check algorithms and assumptions made in software 50 | -------------------------------------------------------------------------------- /src/docs/readme.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |