Browse Source

adding cs240

Derek McQuay 2 years ago
parent
commit
9d4aab12b8
100 changed files with 7976 additions and 0 deletions
  1. 2
    0
      cs240/record-indexer/.gitignore
  2. 1
    0
      cs240/record-indexer/.idea/.name
  3. 17
    0
      cs240/record-indexer/.idea/artifacts/search_gui_jar.xml
  4. 13
    0
      cs240/record-indexer/.idea/codeStyleSettings.xml
  5. 23
    0
      cs240/record-indexer/.idea/compiler.xml
  6. 5
    0
      cs240/record-indexer/.idea/copyright/profiles_settings.xml
  7. 11
    0
      cs240/record-indexer/.idea/dictionaries/film42.xml
  8. 5
    0
      cs240/record-indexer/.idea/encodings.xml
  9. 11
    0
      cs240/record-indexer/.idea/libraries/checkstyle_5_3_all.xml
  10. 15
    0
      cs240/record-indexer/.idea/libraries/commons_io_2.xml
  11. 11
    0
      cs240/record-indexer/.idea/libraries/sqlite_jdbc_3_8_0_20130827_035027_1.xml
  12. 28
    0
      cs240/record-indexer/.idea/misc.xml
  13. 9
    0
      cs240/record-indexer/.idea/modules.xml
  14. 5
    0
      cs240/record-indexer/.idea/scopes/scope_settings.xml
  15. 125
    0
      cs240/record-indexer/.idea/uiDesigner.xml
  16. 7
    0
      cs240/record-indexer/.idea/vcs.xml
  17. 1427
    0
      cs240/record-indexer/.idea/workspace.xml
  18. 200
    0
      cs240/record-indexer/build.xml
  19. 58
    0
      cs240/record-indexer/checkstyle.xml
  20. 107
    0
      cs240/record-indexer/src/client/Client.java
  21. 119
    0
      cs240/record-indexer/src/client/communication/Communicator.java
  22. 20
    0
      cs240/record-indexer/src/client/communication/errors/RemoteServerErrorException.java
  23. 21
    0
      cs240/record-indexer/src/client/communication/errors/UnauthorizedAccessException.java
  24. 113
    0
      cs240/record-indexer/src/client/communication/modules/HttpClient.java
  25. 102
    0
      cs240/record-indexer/src/client/components/FileMenu.java
  26. 147
    0
      cs240/record-indexer/src/client/components/MainWindow.java
  27. 74
    0
      cs240/record-indexer/src/client/components/SplitBase.java
  28. 156
    0
      cs240/record-indexer/src/client/components/downloadModal/DownloadModal.java
  29. 25
    0
      cs240/record-indexer/src/client/components/downloadModal/SampleImage.java
  30. 52
    0
      cs240/record-indexer/src/client/components/downloadModal/SampleImageModal.java
  31. 77
    0
      cs240/record-indexer/src/client/components/fieldHelp/FieldHelp.java
  32. 141
    0
      cs240/record-indexer/src/client/components/formEntry/FormEntry.java
  33. 195
    0
      cs240/record-indexer/src/client/components/formEntry/FormTable.java
  34. 45
    0
      cs240/record-indexer/src/client/components/imagePanel/ImageCell.java
  35. 174
    0
      cs240/record-indexer/src/client/components/imagePanel/ImageControl.java
  36. 36
    0
      cs240/record-indexer/src/client/components/imagePanel/ImagePanel.java
  37. 147
    0
      cs240/record-indexer/src/client/components/imagePanel/ImageTable.java
  38. 291
    0
      cs240/record-indexer/src/client/components/imagePanel/ScalableImage.java
  39. 12
    0
      cs240/record-indexer/src/client/components/imagePanel/listeners/ImageControlsListener.java
  40. 5
    0
      cs240/record-indexer/src/client/components/listeners/DrawingListener.java
  41. 42
    0
      cs240/record-indexer/src/client/components/loginWindow/ErrorLoginDialog.java
  42. 74
    0
      cs240/record-indexer/src/client/components/loginWindow/LoginWindow.java
  43. 53
    0
      cs240/record-indexer/src/client/components/loginWindow/SuccessLoginDialog.java
  44. 22
    0
      cs240/record-indexer/src/client/components/menus/SpellCheckPopup.java
  45. 89
    0
      cs240/record-indexer/src/client/components/spellCheck/SpellingModal.java
  46. 115
    0
      cs240/record-indexer/src/client/components/tableEntry/EntryCellEditor.java
  47. 58
    0
      cs240/record-indexer/src/client/components/tableEntry/EntryCellRenderer.java
  48. 65
    0
      cs240/record-indexer/src/client/components/tableEntry/RecordCellEditor.java
  49. 36
    0
      cs240/record-indexer/src/client/components/tableEntry/RecordCellRenderer.java
  50. 106
    0
      cs240/record-indexer/src/client/components/tableEntry/TableEntry.java
  51. 138
    0
      cs240/record-indexer/src/client/components/tableEntry/TableModel.java
  52. 81
    0
      cs240/record-indexer/src/client/modules/spellChecker/KnownData.java
  53. 120
    0
      cs240/record-indexer/src/client/modules/spellChecker/SpellChecker.java
  54. 6
    0
      cs240/record-indexer/src/client/modules/spellChecker/WordSelectedListener.java
  55. 25
    0
      cs240/record-indexer/src/client/persistence/Cell.java
  56. 349
    0
      cs240/record-indexer/src/client/persistence/ImageState.java
  57. 9
    0
      cs240/record-indexer/src/client/persistence/ImageStateListener.java
  58. 7
    0
      cs240/record-indexer/src/client/persistence/NewProjectListener.java
  59. 131
    0
      cs240/record-indexer/src/client/persistence/Settings.java
  60. 11
    0
      cs240/record-indexer/src/client/persistence/SyncContext.java
  61. 251
    0
      cs240/record-indexer/src/search/Main.java
  62. 24
    0
      cs240/record-indexer/src/search/MainLayout.java
  63. 19
    0
      cs240/record-indexer/src/search/Search.java
  64. 22
    0
      cs240/record-indexer/src/search/elements/FieldButton.java
  65. 10
    0
      cs240/record-indexer/src/search/elements/ImageButton.java
  66. 25
    0
      cs240/record-indexer/src/search/elements/ProjectGroup.java
  67. 10
    0
      cs240/record-indexer/src/search/forms/InputField.java
  68. 132
    0
      cs240/record-indexer/src/search/helpers/Networking.java
  69. 25
    0
      cs240/record-indexer/src/search/helpers/dataModels/ProjectContainer.java
  70. 49
    0
      cs240/record-indexer/src/server/Server.java
  71. 15
    0
      cs240/record-indexer/src/server/controllers/UsersController.java
  72. 142
    0
      cs240/record-indexer/src/server/db/common/Database.java
  73. 10
    0
      cs240/record-indexer/src/server/db/common/SQL.java
  74. 80
    0
      cs240/record-indexer/src/server/db/common/Transaction.java
  75. 235
    0
      cs240/record-indexer/src/server/db/importer/Importer.java
  76. 21
    0
      cs240/record-indexer/src/server/errors/ServerException.java
  77. 77
    0
      cs240/record-indexer/src/server/handlers/DownloadBatchHandler.java
  78. 70
    0
      cs240/record-indexer/src/server/handlers/GetFieldsHandler.java
  79. 58
    0
      cs240/record-indexer/src/server/handlers/GetProjectsHandler.java
  80. 55
    0
      cs240/record-indexer/src/server/handlers/GetSampleImageHandler.java
  81. 85
    0
      cs240/record-indexer/src/server/handlers/SearchHandler.java
  82. 36
    0
      cs240/record-indexer/src/server/handlers/StaticsHandler.java
  83. 75
    0
      cs240/record-indexer/src/server/handlers/SubmitBatchHandler.java
  84. 46
    0
      cs240/record-indexer/src/server/handlers/ValidateUserHandler.java
  85. 76
    0
      cs240/record-indexer/src/server/handlers/common/BaseHanlder.java
  86. 5
    0
      cs240/record-indexer/src/shared/common/BaseModel.java
  87. 22
    0
      cs240/record-indexer/src/shared/communication/common/ARecord.java
  88. 71
    0
      cs240/record-indexer/src/shared/communication/common/Fields.java
  89. 24
    0
      cs240/record-indexer/src/shared/communication/common/Project_Res.java
  90. 56
    0
      cs240/record-indexer/src/shared/communication/common/Tuple.java
  91. 55
    0
      cs240/record-indexer/src/shared/communication/params/DownloadBatch_Param.java
  92. 50
    0
      cs240/record-indexer/src/shared/communication/params/Fields_Param.java
  93. 41
    0
      cs240/record-indexer/src/shared/communication/params/Projects_Param.java
  94. 51
    0
      cs240/record-indexer/src/shared/communication/params/SampleImage_Param.java
  95. 63
    0
      cs240/record-indexer/src/shared/communication/params/Search_Param.java
  96. 85
    0
      cs240/record-indexer/src/shared/communication/params/SubmitBatch_Param.java
  97. 44
    0
      cs240/record-indexer/src/shared/communication/params/ValidateUser_Param.java
  98. 131
    0
      cs240/record-indexer/src/shared/communication/responses/DownloadBatch_Res.java
  99. 61
    0
      cs240/record-indexer/src/shared/communication/responses/Fields_Res.java
  100. 0
    0
      cs240/record-indexer/src/shared/communication/responses/Projects_Res.java

+ 2
- 0
cs240/record-indexer/.gitignore View File

@@ -0,0 +1,2 @@
1
+build/
2
+out/

+ 1
- 0
cs240/record-indexer/.idea/.name View File

@@ -0,0 +1 @@
1
+6-record-indexer

+ 17
- 0
cs240/record-indexer/.idea/artifacts/search_gui_jar.xml View File

@@ -0,0 +1,17 @@
1
+<component name="ArtifactManager">
2
+  <artifact type="jar" name="search_gui:jar">
3
+    <output-path>$PROJECT_DIR$/out/artifacts/search_gui_jar</output-path>
4
+    <root id="archive" name="6-record-indexer.jar">
5
+      <element id="module-output" name="6-record-indexer" />
6
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4.jar" path-in-jar="/" />
7
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-tests.jar" path-in-jar="/" />
8
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-javadoc.jar" path-in-jar="/" />
9
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-sources.jar" path-in-jar="/" />
10
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-test-sources.jar" path-in-jar="/" />
11
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar" path-in-jar="/" />
12
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/checkstyle-5.3-all.jar" path-in-jar="/" />
13
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/junit-4.8.2.jar" path-in-jar="/" />
14
+      <element id="extracted-dir" path="$PROJECT_DIR$/lib/xstream-1.4.2.jar" path-in-jar="/" />
15
+    </root>
16
+  </artifact>
17
+</component>

+ 13
- 0
cs240/record-indexer/.idea/codeStyleSettings.xml View File

@@ -0,0 +1,13 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="ProjectCodeStyleSettingsManager">
4
+    <option name="PER_PROJECT_SETTINGS">
5
+      <value>
6
+        <XML>
7
+          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
8
+        </XML>
9
+      </value>
10
+    </option>
11
+  </component>
12
+</project>
13
+

+ 23
- 0
cs240/record-indexer/.idea/compiler.xml View File

@@ -0,0 +1,23 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="CompilerConfiguration">
4
+    <option name="DEFAULT_COMPILER" value="Javac" />
5
+    <resourceExtensions />
6
+    <wildcardResourcePatterns>
7
+      <entry name="!?*.java" />
8
+      <entry name="!?*.form" />
9
+      <entry name="!?*.class" />
10
+      <entry name="!?*.groovy" />
11
+      <entry name="!?*.scala" />
12
+      <entry name="!?*.flex" />
13
+      <entry name="!?*.kt" />
14
+      <entry name="!?*.clj" />
15
+    </wildcardResourcePatterns>
16
+    <annotationProcessing>
17
+      <profile default="true" name="Default" enabled="false">
18
+        <processorPath useClasspath="true" />
19
+      </profile>
20
+    </annotationProcessing>
21
+  </component>
22
+</project>
23
+

+ 5
- 0
cs240/record-indexer/.idea/copyright/profiles_settings.xml View File

@@ -0,0 +1,5 @@
1
+<component name="CopyrightManager">
2
+  <settings default="">
3
+    <module2copyright />
4
+  </settings>
5
+</component>

+ 11
- 0
cs240/record-indexer/.idea/dictionaries/film42.xml View File

@@ -0,0 +1,11 @@
1
+<component name="ProjectDictionaryState">
2
+  <dictionary name="film42">
3
+    <words>
4
+      <w>accessors</w>
5
+      <w>congratz</w>
6
+      <w>hackery</w>
7
+      <w>thornburg</w>
8
+      <w>tuples</w>
9
+    </words>
10
+  </dictionary>
11
+</component>

+ 5
- 0
cs240/record-indexer/.idea/encodings.xml View File

@@ -0,0 +1,5 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
+</project>
5
+

+ 11
- 0
cs240/record-indexer/.idea/libraries/checkstyle_5_3_all.xml View File

@@ -0,0 +1,11 @@
1
+<component name="libraryTable">
2
+  <library name="checkstyle-5.3-all">
3
+    <CLASSES>
4
+      <root url="jar://$PROJECT_DIR$/lib/checkstyle-5.3-all.jar!/" />
5
+      <root url="jar://$PROJECT_DIR$/lib/junit-4.8.2.jar!/" />
6
+      <root url="jar://$PROJECT_DIR$/lib/xstream-1.4.2.jar!/" />
7
+    </CLASSES>
8
+    <JAVADOC />
9
+    <SOURCES />
10
+  </library>
11
+</component>

+ 15
- 0
cs240/record-indexer/.idea/libraries/commons_io_2.xml View File

@@ -0,0 +1,15 @@
1
+<component name="libraryTable">
2
+  <library name="commons-io-2">
3
+    <CLASSES>
4
+      <root url="file://$PROJECT_DIR$/lib/commons-io-2.4" />
5
+    </CLASSES>
6
+    <JAVADOC>
7
+      <root url="file://$PROJECT_DIR$/lib/commons-io-2.4/docs" />
8
+    </JAVADOC>
9
+    <SOURCES>
10
+      <root url="file://$PROJECT_DIR$/lib/commons-io-2.4" />
11
+    </SOURCES>
12
+    <jarDirectory url="file://$PROJECT_DIR$/lib/commons-io-2.4" recursive="false" />
13
+    <jarDirectory url="file://$PROJECT_DIR$/lib/commons-io-2.4" recursive="false" type="SOURCES" />
14
+  </library>
15
+</component>

+ 11
- 0
cs240/record-indexer/.idea/libraries/sqlite_jdbc_3_8_0_20130827_035027_1.xml View File

@@ -0,0 +1,11 @@
1
+<component name="libraryTable">
2
+  <library name="sqlite-jdbc-3.8.0-20130827.035027-1">
3
+    <CLASSES>
4
+      <root url="jar://$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar!/" />
5
+    </CLASSES>
6
+    <JAVADOC />
7
+    <SOURCES>
8
+      <root url="jar://$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar!/" />
9
+    </SOURCES>
10
+  </library>
11
+</component>

+ 28
- 0
cs240/record-indexer/.idea/misc.xml View File

@@ -0,0 +1,28 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="EntryPointsManager">
4
+    <entry_points version="2.0" />
5
+  </component>
6
+  <component name="JavadocGenerationManager">
7
+    <option name="OUTPUT_DIRECTORY" value="$PROJECT_DIR$/../5-design-document/docs" />
8
+    <option name="OPTION_SCOPE" value="package" />
9
+    <option name="OPTION_HIERARCHY" value="true" />
10
+    <option name="OPTION_NAVIGATOR" value="true" />
11
+    <option name="OPTION_INDEX" value="true" />
12
+    <option name="OPTION_SEPARATE_INDEX" value="true" />
13
+    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
14
+    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
15
+    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
16
+    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
17
+    <option name="OPTION_DEPRECATED_LIST" value="true" />
18
+    <option name="OTHER_OPTIONS" />
19
+    <option name="HEAP_SIZE" />
20
+    <option name="LOCALE" />
21
+    <option name="OPEN_IN_BROWSER" value="true" />
22
+    <option name="OPTION_INCLUDE_LIBS" value="false" />
23
+  </component>
24
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
25
+    <output url="file://$PROJECT_DIR$/out" />
26
+  </component>
27
+</project>
28
+

+ 9
- 0
cs240/record-indexer/.idea/modules.xml View File

@@ -0,0 +1,9 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="ProjectModuleManager">
4
+    <modules>
5
+      <module fileurl="file://$PROJECT_DIR$/6-record-indexer.iml" filepath="$PROJECT_DIR$/6-record-indexer.iml" />
6
+    </modules>
7
+  </component>
8
+</project>
9
+

+ 5
- 0
cs240/record-indexer/.idea/scopes/scope_settings.xml View File

@@ -0,0 +1,5 @@
1
+<component name="DependencyValidationManager">
2
+  <state>
3
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
4
+  </state>
5
+</component>

+ 125
- 0
cs240/record-indexer/.idea/uiDesigner.xml View File

@@ -0,0 +1,125 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="Palette2">
4
+    <group name="Swing">
5
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
6
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
7
+      </item>
8
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
9
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
10
+      </item>
11
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
12
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
13
+      </item>
14
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
15
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
16
+      </item>
17
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
18
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
19
+        <initial-values>
20
+          <property name="text" value="Button" />
21
+        </initial-values>
22
+      </item>
23
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
24
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
25
+        <initial-values>
26
+          <property name="text" value="RadioButton" />
27
+        </initial-values>
28
+      </item>
29
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
30
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
31
+        <initial-values>
32
+          <property name="text" value="CheckBox" />
33
+        </initial-values>
34
+      </item>
35
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
36
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
37
+        <initial-values>
38
+          <property name="text" value="Label" />
39
+        </initial-values>
40
+      </item>
41
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
42
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
43
+          <preferred-size width="150" height="-1" />
44
+        </default-constraints>
45
+      </item>
46
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
47
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
48
+          <preferred-size width="150" height="-1" />
49
+        </default-constraints>
50
+      </item>
51
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
52
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
53
+          <preferred-size width="150" height="-1" />
54
+        </default-constraints>
55
+      </item>
56
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
57
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
58
+          <preferred-size width="150" height="50" />
59
+        </default-constraints>
60
+      </item>
61
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
62
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
63
+          <preferred-size width="150" height="50" />
64
+        </default-constraints>
65
+      </item>
66
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
67
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
68
+          <preferred-size width="150" height="50" />
69
+        </default-constraints>
70
+      </item>
71
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
72
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
73
+      </item>
74
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
75
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
76
+          <preferred-size width="150" height="50" />
77
+        </default-constraints>
78
+      </item>
79
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
80
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
81
+          <preferred-size width="150" height="50" />
82
+        </default-constraints>
83
+      </item>
84
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
85
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
86
+          <preferred-size width="150" height="50" />
87
+        </default-constraints>
88
+      </item>
89
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
90
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
91
+          <preferred-size width="200" height="200" />
92
+        </default-constraints>
93
+      </item>
94
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
95
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
96
+          <preferred-size width="200" height="200" />
97
+        </default-constraints>
98
+      </item>
99
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
100
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
101
+      </item>
102
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
103
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
104
+      </item>
105
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
106
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
107
+      </item>
108
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
109
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
110
+      </item>
111
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
112
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
113
+          <preferred-size width="-1" height="20" />
114
+        </default-constraints>
115
+      </item>
116
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
117
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
118
+      </item>
119
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
120
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
121
+      </item>
122
+    </group>
123
+  </component>
124
+</project>
125
+

+ 7
- 0
cs240/record-indexer/.idea/vcs.xml View File

@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="VcsDirectoryMappings">
4
+    <mapping directory="" vcs="" />
5
+  </component>
6
+</project>
7
+

+ 1427
- 0
cs240/record-indexer/.idea/workspace.xml
File diff suppressed because it is too large
View File


+ 200
- 0
cs240/record-indexer/build.xml View File

@@ -0,0 +1,200 @@
1
+
2
+<project name="Record Indexer" default="compile" basedir=".">
3
+
4
+	<!-- PROPERTIES -->
5
+	<!-- ********** -->	
6
+	
7
+	<!-- Directory containing application source code -->
8
+	<property name="src" location="src"/>
9
+	
10
+	<!-- Directory containing testing source code -->
11
+	<property name="test" location="test"/>
12
+	
13
+	<!-- Directory containing Java libraries -->
14
+	<property name="lib" location="lib"/>
15
+	
16
+	<!-- Directory where the Java compiler puts .class files -->
17
+	<property name="build" location="build"/>
18
+	
19
+	<!-- Directory containing database files -->
20
+	<property name="database" location="db"/>
21
+
22
+	<!-- Directory containing demo files -->
23
+	<property name="demo" location="demo"/>
24
+	
25
+	<!-- Directory containing passoff files -->
26
+	<property name="passoff" location="passoff"/>
27
+	
28
+	<!-- Database file used by the server -->
29
+	<property name="db-file" location="${database}/database.sqlite3"/>
30
+	
31
+	<!-- Database file containing empty tables. -->
32
+	<property name="empty-db-file" location="${database}/template.sqlite3"/>
33
+	
34
+	<!-- File containing the report output by Checkstyle -->
35
+	<property name="checkstyle-report-file" location="checkstyle-report.txt"/>
36
+	
37
+	<!-- Default values for command-line properties.  Values specified on the command-line will override these. -->
38
+	<property name="file" value="demo/indexer_data/Records/Records.xml"/>
39
+	<property name="host" value="localhost"/>
40
+	<property name="port" value="39640"/>
41
+
42
+	<!-- CLASS PATHS -->
43
+	<!-- *********** -->
44
+	<path id="lib-classpath">
45
+		<fileset dir="${lib}">
46
+			<include name="**/*.jar" />
47
+		</fileset>
48
+	</path>
49
+	
50
+	<path id="all-classpath">
51
+		<path refid="lib-classpath"/>
52
+		<pathelement location="${build}"/>
53
+	</path>
54
+	
55
+	<path id="passoff-classpath">
56
+		<path refid="all-classpath"/>
57
+		<pathelement location="${passoff}/server-passoff.jar"/>
58
+	</path>
59
+	
60
+	<!-- TASK DEFINITIONS -->
61
+	<!-- **************** -->
62
+	<taskdef classpathref="lib-classpath" resource="checkstyletask.properties"/>
63
+
64
+
65
+	<!-- TARGETS -->
66
+	<!-- ******* -->
67
+	<target name="init" description="create build directories">
68
+		<tstamp/>
69
+		<mkdir dir="${build}"/>
70
+		<mkdir dir="${passoff}"/>
71
+	</target>
72
+
73
+	<target name="clean" description="delete build files and directories">
74
+		<delete dir="${build}"/>
75
+		<delete dir="${passoff}"/>
76
+	</target>
77
+
78
+	<target name="compile" depends="init" description="compile the source code">
79
+		<javac srcdir="${src}" classpathref="lib-classpath" destdir="${build}" debug="true" includeantruntime="true" />
80
+		<javac srcdir="${test}" classpathref="lib-classpath" destdir="${build}" debug="true" includeantruntime="true" />
81
+	</target>
82
+	
83
+	<!-- ant importer -Dfile=<INDEXER_DATA_XML_FILE> -->
84
+	<!-- EXAMPLE: ant importer -Dfile=dir1/dir2/indexer_data.xml -->
85
+	<target name="import" depends="compile" description="import indexer data">
86
+		<copy file="${empty-db-file}" tofile="${db-file}" overwrite="true"/>
87
+		<java classname="server.db.importer.Importer" fork="yes">
88
+			<classpath>
89
+				<path refid="all-classpath"/>
90
+			</classpath>
91
+			<arg value="${file}"/>
92
+			<assertions>
93
+				<enable/>
94
+			</assertions>
95
+		</java>
96
+	</target>
97
+		
98
+	<!-- ant server {-Dport=<SERVER_PORT_NUMBER>} -->
99
+	<!-- EXAMPLE: ant server -Dport=39640 -->
100
+	<!-- If port number is omitted, run on default port. -->
101
+	<!-- EXAMPLE: ant server -->
102
+	<target name="server" depends="compile" description="run server on specified port">
103
+		<java classname="server.Server" fork="yes">
104
+			<classpath>
105
+				<path refid="all-classpath"/>
106
+			</classpath>
107
+			<arg value="${port}"/>
108
+			<assertions>
109
+				<enable/>
110
+			</assertions>
111
+		</java>
112
+	</target>
113
+
114
+	<target name="server-gui" depends="compile" description="run the server test gui">
115
+		<java classname="servertester.GuiTester" fork="yes">
116
+			<classpath>
117
+				<path refid="all-classpath"/>
118
+			</classpath>
119
+			<assertions>
120
+				<enable/>
121
+			</assertions>
122
+		</java>
123
+	</target>
124
+	
125
+	<target name="server-tests" depends="compile" description="run automated server tests">
126
+		<java classname="server.ServerUnitTests" fork="yes">
127
+			<classpath>
128
+				<path refid="all-classpath"/>
129
+			</classpath>
130
+			<assertions>
131
+				<enable/>
132
+			</assertions>
133
+		</java>
134
+	</target>
135
+	
136
+	
137
+	<!-- ant server-passoff {-Dhost=<SERVER_HOST>} {-Dport=<SERVER_PORT_NUMBER>} -->
138
+	<!-- EXAMPLE: ant server-passoff -Dhost=testserver.cs.byu.edu -Dport=39640 -->
139
+	<!-- If host and/or port number are omitted, default values are used. -->
140
+	<!-- EXAMPLE: ant server-passoff -->
141
+	<target name="server-passoff" depends="compile" description="run server passoff using server on specified host and port">
142
+		<java classname="passoff.ServerPassoff" fork="yes">
143
+			<classpath>
144
+				<path refid="passoff-classpath"/>
145
+			</classpath>
146
+			<arg value="${host}"/>
147
+			<arg value="${port}"/>
148
+			<assertions>
149
+				<enable/>
150
+			</assertions>
151
+		</java>
152
+	</target>
153
+	
154
+	<!-- ant client {-Dhost=<SERVER_HOST>} {-Dport=<SERVER_PORT_NUMBER>} -->
155
+	<!-- EXAMPLE: ant client -Dhost=testserver.cs.byu.edu -Dport=39640 -->
156
+	<!-- If host and/or port number are omitted, default values are used. -->
157
+	<!-- EXAMPLE: ant client -->
158
+	<target name="client" depends="compile" description="run client using server on specified host and port">
159
+				<java classname="client.Client" fork="yes">
160
+			<classpath>
161
+				<path refid="all-classpath"/>
162
+			</classpath>
163
+			<arg value="${host}"/>
164
+			<arg value="${port}"/>
165
+			<assertions>
166
+				<enable/>
167
+			</assertions>
168
+		</java>
169
+	</target>
170
+	
171
+	<target name="client-tests" depends="compile" description="run automated client tests">
172
+		<java classname="client.ClientUnitTests" fork="yes">
173
+			<classpath>
174
+				<path refid="all-classpath"/>
175
+			</classpath>
176
+			<assertions>
177
+				<enable/>
178
+			</assertions>
179
+		</java>
180
+	</target>
181
+	
182
+	<target name="checkstyle" depends="compile" description="run checkstyle on all source code">
183
+		<checkstyle config="checkstyle.xml">
184
+			<fileset dir="${src}" includes="**/*.java">
185
+			</fileset>
186
+			<formatter type="plain" toFile="${checkstyle-report-file}"/>
187
+			<classpath>
188
+				<pathelement location="${build}"/>
189
+			</classpath>
190
+		</checkstyle>
191
+	</target>
192
+	
193
+	<target name="demo" description="run the demo">
194
+		<java jar="${demo}/record-indexer-demo.jar" fork="yes" dir="${demo}">
195
+		</java>
196
+	</target>
197
+
198
+	
199
+</project>
200
+

+ 58
- 0
cs240/record-indexer/checkstyle.xml View File

@@ -0,0 +1,58 @@
1
+<?xml version="1.0"?>
2
+<!DOCTYPE module PUBLIC
3
+          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
4
+          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
5
+
6
+<module name="Checker">
7
+	
8
+	<module name="FileLength">
9
+		<property name="max" value="2000"/>
10
+	</module>
11
+
12
+	<module name="TreeWalker">
13
+	
14
+		<property name="tabWidth" value="4"/>
15
+
16
+		<module name="NestedForDepth">
17
+    		<property name="max" value="1"/>
18
+		</module>
19
+
20
+		<module name="NestedIfDepth">
21
+    		<property name="max" value="2"/>
22
+		</module>
23
+	
24
+		<module name="NestedTryDepth">
25
+    		<property name="max" value="1"/>
26
+		</module>
27
+	
28
+		<module name="BooleanExpressionComplexity">
29
+    		<property name="max" value="5"/>
30
+		</module>
31
+	
32
+		<module name="CyclomaticComplexity">
33
+	    	<property name="max" value="10"/>
34
+		</module>
35
+	
36
+		<module name="NPathComplexity">
37
+	    	<property name="max" value="200"/>
38
+		</module>
39
+	
40
+		<module name="LineLength">
41
+			<property name="max" value="100"/>
42
+		</module>
43
+	
44
+		<module name="MethodLength">
45
+			<property name="max" value="120"/>
46
+			<property name="countEmpty" value="false"/>	
47
+		</module>
48
+	
49
+		<module name="ParameterNumber">
50
+			<property name="max" value="7"/>
51
+			<property name="tokens" value="METHOD_DEF"/>
52
+		</module>
53
+	
54
+	</module>
55
+
56
+</module>
57
+    
58
+

+ 107
- 0
cs240/record-indexer/src/client/Client.java View File

@@ -0,0 +1,107 @@
1
+package client;
2
+
3
+import client.communication.Communicator;
4
+import client.components.MainWindow;
5
+import client.components.loginWindow.ErrorLoginDialog;
6
+import client.components.loginWindow.LoginWindow;
7
+import client.components.loginWindow.SuccessLoginDialog;
8
+import shared.communication.params.ValidateUser_Param;
9
+import shared.communication.responses.ValidateUser_Res;
10
+
11
+import javax.swing.*;
12
+import java.awt.*;
13
+import java.awt.event.*;
14
+
15
+public class Client {
16
+
17
+    private LoginWindow loginWindow;
18
+    private Communicator communicator;
19
+
20
+    public Client(Communicator communicator) {
21
+        this.communicator = communicator;
22
+    }
23
+
24
+    public void run() {
25
+        loginWindow = new LoginWindow(communicator);
26
+        loginWindow.addLoginListener(loginListener);
27
+
28
+        // Run
29
+        EventQueue.invokeLater(new Runnable() {
30
+            public void run() {
31
+                loginWindow.setVisible(true);
32
+
33
+            }
34
+        });
35
+    }
36
+
37
+    public static void main(String[] args) {
38
+        // Create Window
39
+        String host = args[0];
40
+        String port = args[1];
41
+        String server = "http://"+host+":"+port+"/";
42
+        Communicator communicator = new Communicator(server);
43
+
44
+        Client client = new Client(communicator);
45
+        client.run();
46
+    }
47
+
48
+    private ActionListener loginListener = new AbstractAction() {
49
+        @Override
50
+        public void actionPerformed(ActionEvent e) {
51
+            ValidateUser_Param param = new ValidateUser_Param();
52
+            param.setUsername(loginWindow.getUsername());
53
+            param.setPassword(loginWindow.getPassword());
54
+
55
+            try {
56
+                ValidateUser_Res validateUserRes;
57
+                validateUserRes = communicator.validateUser(param);
58
+
59
+                loginWindow.setVisible(false);
60
+
61
+                SuccessLoginDialog successLoginDialog = new SuccessLoginDialog(validateUserRes);
62
+                successLoginDialog.addWindowListener(openMainWindowListener);
63
+                successLoginDialog.setVisible(true);
64
+
65
+
66
+            } catch (Exception execption) {
67
+                ErrorLoginDialog errorLoginDialog = new ErrorLoginDialog();
68
+                errorLoginDialog.setVisible(true);
69
+            }
70
+        }
71
+    };
72
+
73
+    private WindowListener openMainWindowListener = new WindowAdapter() {
74
+        @Override
75
+        public void windowClosed(WindowEvent e) {
76
+            super.windowClosed(e);
77
+
78
+            // Run
79
+            EventQueue.invokeLater(new Runnable() {
80
+                public void run() {
81
+                    MainWindow frame = new MainWindow(communicator, loginWindow.getUsername(),
82
+                        loginWindow.getPassword());
83
+                    frame.addWindowListener(logoutListener);
84
+                    frame.setVisible(true);
85
+                }
86
+            });
87
+        }
88
+    };
89
+
90
+    private WindowListener logoutListener = new WindowAdapter() {
91
+        @Override
92
+        public void windowClosed(WindowEvent e) {
93
+            super.windowClosed(e);
94
+
95
+            loginWindow = new LoginWindow(communicator);
96
+            loginWindow.addLoginListener(loginListener);
97
+
98
+            // Run
99
+            EventQueue.invokeLater(new Runnable() {
100
+                public void run() {
101
+                    loginWindow.setVisible(true);
102
+                }
103
+            });
104
+        }
105
+    };
106
+
107
+}

+ 119
- 0
cs240/record-indexer/src/client/communication/Communicator.java View File

@@ -0,0 +1,119 @@
1
+package client.communication;
2
+
3
+import client.communication.errors.RemoteServerErrorException;
4
+import client.communication.errors.UnauthorizedAccessException;
5
+import client.communication.modules.HttpClient;
6
+import shared.communication.params.*;
7
+import shared.communication.responses.*;
8
+
9
+import java.io.ByteArrayOutputStream;
10
+
11
+public class Communicator {
12
+
13
+    public Communicator(String serverPath) {
14
+        this.serverPath = serverPath;
15
+    }
16
+
17
+    private String serverPath;
18
+
19
+    public String getServerPath() {
20
+        return serverPath;
21
+    }
22
+
23
+    public ValidateUser_Res validateUser(ValidateUser_Param user)
24
+        throws UnauthorizedAccessException, RemoteServerErrorException {
25
+
26
+        String resource = "validateUser/";
27
+        String response = HttpClient.post(serverPath + resource, user.toXML());
28
+
29
+        if(response == null)
30
+            return null;
31
+
32
+        return ValidateUser_Res.serialize(response);
33
+    }
34
+
35
+    public Projects_Res getProjects(Projects_Param projects)
36
+        throws UnauthorizedAccessException, RemoteServerErrorException {
37
+
38
+        String resource = "getProjects/";
39
+        String response = HttpClient.post(serverPath + resource, projects.toXML());
40
+
41
+        if(response == null)
42
+            return null;
43
+
44
+        return Projects_Res.serialize(response);
45
+    }
46
+
47
+    public SampleImage_Res getSampleImage(SampleImage_Param sampleImage)
48
+        throws UnauthorizedAccessException, RemoteServerErrorException {
49
+
50
+        String resource = "getSampleImage/";
51
+        String response = HttpClient.post(serverPath + resource, sampleImage.toXML());
52
+
53
+        if(response == null)
54
+            return null;
55
+
56
+        return SampleImage_Res.serialize(response);
57
+    }
58
+
59
+    public DownloadBatch_Res downloadBatch(DownloadBatch_Param downloadBatch)
60
+        throws UnauthorizedAccessException, RemoteServerErrorException {
61
+
62
+        String resource = "downloadBatch/";
63
+        String response = HttpClient.post(serverPath + resource, downloadBatch.toXML());
64
+
65
+        if(response == null)
66
+            return null;
67
+
68
+        return DownloadBatch_Res.serialize(response);
69
+    }
70
+
71
+    public SubmitBatch_Res submitBatch(SubmitBatch_Param submitBatch)
72
+        throws UnauthorizedAccessException, RemoteServerErrorException {
73
+
74
+        String resource = "submitBatch/";
75
+        String response = HttpClient.post(serverPath + resource, submitBatch.toXML());
76
+
77
+        if(response == null)
78
+            return null;
79
+
80
+        return SubmitBatch_Res.serialize(response);
81
+    }
82
+
83
+    public Fields_Res getFields(Fields_Param fields)
84
+        throws UnauthorizedAccessException, RemoteServerErrorException {
85
+
86
+        String resource = "getFields/";
87
+        String response = HttpClient.post(serverPath + resource, fields.toXML());
88
+
89
+        if(response == null)
90
+            return null;
91
+
92
+        return Fields_Res.serialize(response);
93
+    }
94
+
95
+    public Search_Res search(Search_Param search)
96
+        throws UnauthorizedAccessException, RemoteServerErrorException {
97
+
98
+        String resource = "search/";
99
+        String response = HttpClient.post(serverPath + resource, search.toXML());
100
+
101
+        if(response == null)
102
+            return null;
103
+
104
+        return Search_Res.serialize(response);
105
+    }
106
+
107
+    public ByteArrayOutputStream downloadStatic(String resource) {
108
+
109
+        try {
110
+            return HttpClient.getStatic(serverPath+resource);
111
+        } catch (UnauthorizedAccessException e) {
112
+            return null;
113
+        } catch (RemoteServerErrorException e) {
114
+            return null;
115
+        }
116
+
117
+    }
118
+
119
+}

+ 20
- 0
cs240/record-indexer/src/client/communication/errors/RemoteServerErrorException.java View File

@@ -0,0 +1,20 @@
1
+package client.communication.errors;
2
+
3
+public class RemoteServerErrorException extends Exception {
4
+
5
+    public RemoteServerErrorException() {
6
+    }
7
+
8
+    public RemoteServerErrorException(String message) {
9
+        super(message);
10
+    }
11
+
12
+    public RemoteServerErrorException(Throwable throwable) {
13
+        super(throwable);
14
+    }
15
+
16
+    public RemoteServerErrorException(String message, Throwable throwable) {
17
+        super(message, throwable);
18
+    }
19
+
20
+}

+ 21
- 0
cs240/record-indexer/src/client/communication/errors/UnauthorizedAccessException.java View File

@@ -0,0 +1,21 @@
1
+package client.communication.errors;
2
+
3
+@SuppressWarnings("serial")
4
+public class UnauthorizedAccessException extends Exception {
5
+
6
+    public UnauthorizedAccessException() {
7
+    }
8
+
9
+    public UnauthorizedAccessException(String message) {
10
+        super(message);
11
+    }
12
+
13
+    public UnauthorizedAccessException(Throwable throwable) {
14
+        super(throwable);
15
+    }
16
+
17
+    public UnauthorizedAccessException(String message, Throwable throwable) {
18
+        super(message, throwable);
19
+    }
20
+
21
+}

+ 113
- 0
cs240/record-indexer/src/client/communication/modules/HttpClient.java View File

@@ -0,0 +1,113 @@
1
+package client.communication.modules;
2
+
3
+import client.communication.errors.RemoteServerErrorException;
4
+import client.communication.errors.UnauthorizedAccessException;
5
+
6
+import java.io.*;
7
+import java.net.HttpURLConnection;
8
+import java.net.MalformedURLException;
9
+import java.net.URL;
10
+
11
+public class HttpClient {
12
+
13
+    private static InputStream request(String url, String method, String request)
14
+        throws RemoteServerErrorException, UnauthorizedAccessException{
15
+
16
+        try {
17
+            URL requestURL = new URL(url);
18
+            HttpURLConnection connection = (HttpURLConnection) requestURL.openConnection();
19
+
20
+            // We can generalize, whatever
21
+            connection.setDoOutput(true);
22
+
23
+            connection.setRequestMethod(method);
24
+
25
+            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
26
+                    connection.getOutputStream());
27
+            outputStreamWriter.write(request);
28
+            outputStreamWriter.close();
29
+
30
+            switch (connection.getResponseCode()) {
31
+                case HttpURLConnection.HTTP_OK:
32
+                    return connection.getInputStream();
33
+                case HttpURLConnection.HTTP_UNAUTHORIZED:
34
+                    throw new UnauthorizedAccessException();
35
+                default:
36
+                    throw new RemoteServerErrorException();
37
+            }
38
+
39
+        } catch (MalformedURLException e) {
40
+            throw new RemoteServerErrorException();
41
+        } catch (IOException e) {
42
+            throw new RemoteServerErrorException();
43
+        }
44
+    }
45
+
46
+    public static String get(String url)
47
+        throws UnauthorizedAccessException, RemoteServerErrorException {
48
+
49
+        InputStream response = request(url, "GET", "");
50
+        return inputStreamToString(response);
51
+    }
52
+
53
+    public static String post(String url, String req)
54
+        throws UnauthorizedAccessException, RemoteServerErrorException {
55
+
56
+        InputStream response = request(url, "POST", req);
57
+        return inputStreamToString(response);
58
+    }
59
+
60
+    public static ByteArrayOutputStream getStatic(String url)
61
+        throws UnauthorizedAccessException, RemoteServerErrorException {
62
+
63
+        InputStream response = request(url, "GET", "");
64
+
65
+        if(response != null) {
66
+            try {
67
+
68
+                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
69
+
70
+
71
+                byte[] byteArray = new byte[512];
72
+
73
+                int bytesRead = 0;
74
+                while((bytesRead = response.read(byteArray)) != -1) {
75
+                    byteArrayOutputStream.write(byteArray, 0, bytesRead);
76
+                }
77
+
78
+                return byteArrayOutputStream;
79
+
80
+
81
+            } catch (IOException e) {
82
+                return null;
83
+            }
84
+        }
85
+        return null;
86
+    }
87
+
88
+    private static String inputStreamToString(InputStream inputStream) {
89
+        StringBuilder stringBuilder = new StringBuilder();
90
+        BufferedReader bufferedReader =  new BufferedReader(
91
+                new InputStreamReader(inputStream));
92
+
93
+        String line;
94
+        try {
95
+            while ((line = bufferedReader.readLine()) != null) {
96
+                stringBuilder.append(line);
97
+            }
98
+        } catch (IOException e) {
99
+            e.printStackTrace();
100
+        } finally {
101
+            try { bufferedReader.close(); } catch (IOException e) {
102
+                e.printStackTrace(); }
103
+        }
104
+
105
+        try {
106
+            inputStream.close();
107
+        } catch (IOException e) {
108
+
109
+        }
110
+        return stringBuilder.toString();
111
+    }
112
+
113
+}

+ 102
- 0
cs240/record-indexer/src/client/components/FileMenu.java View File

@@ -0,0 +1,102 @@
1
+package client.components;
2
+
3
+import client.communication.Communicator;
4
+import client.components.downloadModal.DownloadModal;
5
+import client.components.loginWindow.ErrorLoginDialog;
6
+import client.persistence.ImageState;
7
+import client.persistence.NewProjectListener;
8
+
9
+import javax.swing.*;
10
+import java.awt.*;
11
+import java.awt.event.ActionEvent;
12
+import java.awt.event.ActionListener;
13
+import java.awt.event.WindowEvent;
14
+
15
+public class FileMenu extends JMenuBar {
16
+    private MainWindow mainWindow;
17
+    private Communicator communicator;
18
+    private ImageState imageState;
19
+    private JMenuItem eMenuItem1;
20
+
21
+    public FileMenu(MainWindow mainWindow, Communicator communicator, ImageState imageState) {
22
+        this.mainWindow = mainWindow;
23
+        this.communicator = communicator;
24
+        this.imageState = imageState;
25
+
26
+        this.imageState.addNewProjectListener(newProjectListener);
27
+
28
+        setupView();
29
+    }
30
+
31
+    private void setupView() {
32
+        // Prevents menu items from filling the whole length
33
+        this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
34
+
35
+        JMenu file1 = new JMenu("File");
36
+
37
+        eMenuItem1 = new JMenuItem("Download Batch");
38
+        eMenuItem1.addActionListener(downloadBatchAction);
39
+        eMenuItem1.setEnabled(!imageState.isHasImage());
40
+        eMenuItem1.setToolTipText("Exit application");
41
+
42
+        JMenuItem eMenuItem2 = new JMenuItem("Logout");
43
+        eMenuItem2.addActionListener(logoutAction);
44
+        eMenuItem2.setToolTipText("Exit application");
45
+
46
+        JMenuItem eMenuItem3 = new JMenuItem("Exit");
47
+        eMenuItem3.addActionListener(exitAction);
48
+        eMenuItem2.setToolTipText("Exit application");
49
+
50
+        file1.add(eMenuItem1);
51
+        file1.add(eMenuItem2);
52
+        file1.add(eMenuItem3);
53
+
54
+        // Add to self
55
+        this.add(file1);
56
+        this.setBackground(Color.WHITE);
57
+    }
58
+
59
+    private void updateSettings() {
60
+        imageState.getSettings().setWindowHeight(mainWindow.getHeight());
61
+        imageState.getSettings().setWindowWidth(mainWindow.getWidth());
62
+
63
+        Point point = mainWindow.getLocationOnScreen();
64
+        imageState.getSettings().setWindowPositionX((int) point.getX());
65
+        imageState.getSettings().setWindowPositionY((int) point.getY());
66
+        imageState.save();
67
+    }
68
+
69
+
70
+    private ActionListener downloadBatchAction = new AbstractAction() {
71
+        @Override
72
+        public void actionPerformed(ActionEvent e) {
73
+            DownloadModal downloadModal = new DownloadModal(imageState, communicator);
74
+            downloadModal.setVisible(true);
75
+        }
76
+    };
77
+
78
+    private ActionListener logoutAction = new AbstractAction() {
79
+        @Override
80
+        public void actionPerformed(ActionEvent e) {
81
+            updateSettings();
82
+            mainWindow.dispose();
83
+        }
84
+    };
85
+
86
+    private ActionListener exitAction = new AbstractAction() {
87
+        @Override
88
+        public void actionPerformed(ActionEvent e) {
89
+            updateSettings();
90
+            System.exit(1);
91
+        }
92
+    };
93
+
94
+    private NewProjectListener newProjectListener = new NewProjectListener() {
95
+        @Override
96
+        public void hasNewProject() {
97
+            boolean status = imageState.isHasImage();
98
+            eMenuItem1.setEnabled(!status);
99
+        }
100
+    };
101
+
102
+}

+ 147
- 0
cs240/record-indexer/src/client/components/MainWindow.java View File

@@ -0,0 +1,147 @@
1
+package client.components;
2
+
3
+import client.communication.Communicator;
4
+import client.components.downloadModal.DownloadModal;
5
+import client.components.imagePanel.ImagePanel;
6
+import client.persistence.Cell;
7
+import client.persistence.ImageState;
8
+import client.persistence.NewProjectListener;
9
+import client.persistence.Settings;
10
+
11
+import javax.swing.*;
12
+import java.awt.*;
13
+import java.awt.event.WindowAdapter;
14
+import java.awt.event.WindowEvent;
15
+import java.awt.event.WindowListener;
16
+import java.beans.PropertyChangeEvent;
17
+import java.beans.PropertyChangeListener;
18
+import java.io.*;
19
+
20
+public class MainWindow extends JFrame implements Serializable {
21
+
22
+    public ImageState imageState;
23
+    private Communicator communicator;
24
+
25
+    JSplitPane body = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JPanel(), new JPanel());
26
+
27
+    public MainWindow(Communicator communicator, String username, String password) {
28
+        Settings settings = loadSettings(username);
29
+
30
+        this.imageState = loadImageState(username);
31
+
32
+        if(this.imageState == null) {
33
+            this.imageState = new ImageState(settings, communicator, username, password);
34
+        } else {
35
+            this.imageState.setCommunicator(communicator);
36
+        }
37
+
38
+        this.imageState.setSettings(settings);
39
+
40
+        this.imageState.addNewProjectListener(newProjectListener);
41
+        this.communicator = communicator;
42
+
43
+        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
44
+
45
+        this.setSize(settings.getWindowWidth(), settings.getWindowHeight());
46
+        this.setLocation(settings.getWindowPositionX(), settings.getWindowPositionY());
47
+
48
+        setupView();
49
+
50
+        this.imageState.initEvents();
51
+        this.addWindowListener(windowListener);
52
+    }
53
+
54
+    private void setupView() {
55
+        setupFileMenu();
56
+        setupImagePanel();
57
+        setupSplitView();
58
+
59
+        this.add(body, BorderLayout.CENTER);
60
+
61
+        body.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
62
+            @Override
63
+            public void propertyChange(PropertyChangeEvent pce) {
64
+                int dividerLocation = body.getDividerLocation();
65
+
66
+                imageState.getSettings().setBaseSplitY(dividerLocation);
67
+            }
68
+        });
69
+    }
70
+
71
+    private void setupFileMenu() {
72
+        // Setup File Menu
73
+        this.add(new FileMenu(this, communicator, imageState), BorderLayout.NORTH);
74
+    }
75
+
76
+    private void setupImagePanel() {
77
+        body.setTopComponent(new ImagePanel(imageState));
78
+    }
79
+
80
+    private void setupSplitView() {
81
+        SplitBase splitBase = new SplitBase(imageState, communicator);
82
+
83
+        body.setBottomComponent(splitBase);
84
+        body.setBorder(null);
85
+        body.setDividerLocation(imageState.getSettings().getBaseSplitY());
86
+    }
87
+
88
+    public ImageState loadImageState(String username) {
89
+        File dest = new File("profiles/"+username);
90
+        if(dest.exists()) {
91
+            FileInputStream fis = null;
92
+            ObjectInputStream in = null;
93
+            try {
94
+                fis = new FileInputStream("profiles/"+username+"/state.ser");
95
+                in = new ObjectInputStream(fis);
96
+                return (ImageState)in.readObject();
97
+            } catch (IOException e) {
98
+                e.printStackTrace();
99
+            } catch (ClassNotFoundException e) {
100
+                e.printStackTrace();
101
+            }
102
+        }
103
+
104
+        return null;
105
+    }
106
+
107
+    public Settings loadSettings(String username) {
108
+        File dest = new File("profiles/"+username);
109
+        if(dest.exists()) {
110
+            FileInputStream fis = null;
111
+            ObjectInputStream in = null;
112
+            try {
113
+                fis = new FileInputStream("profiles/"+username+"/settings.ser");
114
+                in = new ObjectInputStream(fis);
115
+                return (Settings)in.readObject();
116
+            } catch (IOException e) {
117
+                e.printStackTrace();
118
+            } catch (ClassNotFoundException e) {
119
+                e.printStackTrace();
120
+            }
121
+        }
122
+
123
+        return Settings.defaultSettings();
124
+    }
125
+
126
+    private WindowListener windowListener = new WindowAdapter() {
127
+        @Override
128
+        public void windowClosing(WindowEvent e) {
129
+            super.windowClosing(e);
130
+
131
+        }
132
+
133
+        @Override
134
+        public void windowClosed(WindowEvent e) {
135
+            super.windowClosed(e);
136
+
137
+        }
138
+    };
139
+
140
+    private NewProjectListener newProjectListener = new NewProjectListener() {
141
+        @Override
142
+        public void hasNewProject() {
143
+
144
+
145
+        }
146
+    };
147
+}

+ 74
- 0
cs240/record-indexer/src/client/components/SplitBase.java View File

@@ -0,0 +1,74 @@
1
+package client.components;
2
+
3
+import client.communication.Communicator;
4
+import client.components.fieldHelp.FieldHelp;
5
+import client.components.formEntry.FormEntry;
6
+import client.persistence.SyncContext;
7
+import client.components.tableEntry.TableEntry;
8
+import client.persistence.Cell;
9
+import client.persistence.ImageState;
10
+
11
+import javax.swing.*;
12
+import javax.swing.event.ChangeEvent;
13
+import javax.swing.event.ChangeListener;
14
+import java.beans.PropertyChangeEvent;
15
+import java.beans.PropertyChangeListener;
16
+
17
+public class SplitBase extends JSplitPane {
18
+
19
+    private ImageState imageState;
20
+    private JTabbedPane tabbedPane;
21
+    private TableEntry tableEntry;
22
+    private FormEntry formEntry;
23
+    private Communicator communicator;
24
+
25
+    public SplitBase(ImageState imageState, Communicator communicator) {
26
+        this.imageState = imageState;
27
+        this.communicator = communicator;
28
+
29
+        setupView();
30
+
31
+    }
32
+
33
+    private void setupView() {
34
+        tabbedPane = new JTabbedPane();
35
+        tabbedPane.addChangeListener(changeListener);
36
+
37
+        tableEntry = new TableEntry(imageState);
38
+        tabbedPane.addTab("Table Entry", tableEntry);
39
+
40
+        formEntry = new FormEntry(imageState);
41
+        tabbedPane.addTab("Form Entry", formEntry);
42
+
43
+        this.setLeftComponent(tabbedPane);
44
+
45
+        JTabbedPane tabbedPane2 = new JTabbedPane();
46
+        tabbedPane2.addTab("Field Help", new FieldHelp(imageState, communicator));
47
+        tabbedPane2.addTab("Image Navigator", new JPanel());
48
+
49
+        this.setRightComponent(tabbedPane2);
50
+
51
+        this.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
52
+            @Override
53
+            public void propertyChange(PropertyChangeEvent pce) {
54
+                int dividerLocation = getDividerLocation();
55
+
56
+                imageState.getSettings().setBaseSplitX(dividerLocation);
57
+            }
58
+        });
59
+
60
+
61
+        this.setDividerLocation(imageState.getSettings().getBaseSplitX());
62
+
63
+    }
64
+
65
+    private ChangeListener changeListener = new ChangeListener() {
66
+        @Override
67
+        public void stateChanged(ChangeEvent e) {
68
+            if(tabbedPane.getSelectedIndex() == 1) {
69
+                formEntry.becameVisible();
70
+            }
71
+        }
72
+    };
73
+
74
+}

+ 156
- 0
cs240/record-indexer/src/client/components/downloadModal/DownloadModal.java View File

@@ -0,0 +1,156 @@
1
+package client.components.downloadModal;
2
+
3
+import client.communication.Communicator;
4
+import client.communication.errors.RemoteServerErrorException;
5
+import client.communication.errors.UnauthorizedAccessException;
6
+import client.persistence.ImageState;
7
+import shared.communication.common.Project_Res;
8
+import shared.communication.params.Projects_Param;
9
+import shared.communication.params.SampleImage_Param;
10
+import shared.communication.responses.Projects_Res;
11
+import shared.communication.responses.SampleImage_Res;
12
+
13
+import javax.imageio.ImageIO;
14
+import javax.swing.*;
15
+import java.awt.*;
16
+import java.awt.event.ActionEvent;
17
+import java.awt.event.ActionListener;
18
+import java.awt.event.WindowEvent;
19
+import java.awt.image.BufferedImage;
20
+import java.io.IOException;
21
+import java.net.URL;
22
+import java.util.*;
23
+import java.util.List;
24
+
25
+public class DownloadModal extends JDialog {
26
+
27
+    private ImageState imageState;
28
+    private Communicator communicator;
29
+    private List<Project_Res> projects;
30
+    private JComboBox batchSelect;
31
+
32
+
33
+    public DownloadModal(ImageState imageState, Communicator communicator) {
34
+        this.imageState = imageState;
35
+        this.communicator = communicator;
36
+
37
+        setupView();
38
+    }
39
+
40
+    private void setupView() {
41
+        this.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
42
+        this.setTitle("Download Image");
43
+        this.setSize(350, 100);
44
+        this.setResizable(false);
45
+        this.setLocationRelativeTo(null);
46
+        this.setLayout(new FlowLayout());
47
+
48
+        JLabel label = new JLabel("Project: ");
49
+        this.add(label);
50
+
51
+        projects = getProjects().getProjectsList();
52
+
53
+        List<String> values = getProjectNames();
54
+
55
+        batchSelect = new JComboBox(values.toArray());
56
+        this.add(batchSelect);
57
+
58
+        JButton sampleImageButton = new JButton("Sample Image?");
59
+        sampleImageButton.addActionListener(getSampleImageListener);
60
+        this.add(sampleImageButton);
61
+
62
+        JButton cancelButton = new JButton("Cancel");
63
+        cancelButton.addActionListener(closeListener);
64
+        this.add(cancelButton);
65
+
66
+        JButton downloadButton = new JButton("Download");
67
+        downloadButton.addActionListener(downloadListener);
68
+        this.add(downloadButton);
69
+    }
70
+
71
+    private Projects_Res getProjects() {
72
+        Projects_Param param = new Projects_Param();
73
+        param.setUsername(imageState.getUsername());
74
+        param.setPassword(imageState.getPassword());
75
+
76
+        try {
77
+            return communicator.getProjects(param);
78
+        } catch (Exception e) {
79
+            e.printStackTrace();
80
+        }
81
+
82
+        return null;
83
+    }
84
+
85
+    private SampleImage_Res getSampleImage(int projectId) {
86
+        SampleImage_Param param = new SampleImage_Param();
87
+        param.setUsername(imageState.getUsername());
88
+        param.setPassword(imageState.getPassword());
89
+        param.setProjectId(projectId);
90
+
91
+        try {
92
+            return communicator.getSampleImage(param);
93
+        } catch (Exception e) {
94
+
95
+        }
96
+        return null;
97
+    }
98
+
99
+    private ActionListener getSampleImageListener = new AbstractAction() {
100
+        @Override
101
+        public void actionPerformed(ActionEvent e) {
102
+            String projectTitle = (String)batchSelect.getSelectedItem();
103
+            int projectId = getProjectIdForName(projectTitle);
104
+            SampleImage_Res res = getSampleImage(projectId);
105
+
106
+            String fullPath = communicator.getServerPath() + res.getUrl();
107
+
108
+            SampleImageModal sampleImageModal = new SampleImageModal(fullPath);
109
+            sampleImageModal.setVisible(true);
110
+
111
+        }
112
+    };
113
+
114
+    private ActionListener closeListener = new AbstractAction() {
115
+        @Override
116
+        public void actionPerformed(ActionEvent e) {
117
+            setVisible(false);
118
+            dispatchEvent(new WindowEvent(DownloadModal.this, WindowEvent.WINDOW_CLOSING));
119
+        }
120
+    };
121
+
122
+    private ActionListener downloadListener = new AbstractAction() {
123
+        @Override
124
+        public void actionPerformed(ActionEvent e) {
125
+            String projectTitle = (String)batchSelect.getSelectedItem();
126
+            int projectId = getProjectIdForName(projectTitle);
127
+
128
+            imageState.downloadProject(projectId);
129
+
130
+            setVisible(false);
131
+            dispatchEvent(new WindowEvent(DownloadModal.this, WindowEvent.WINDOW_CLOSING));
132
+        }
133
+    };
134
+
135
+    private int getProjectIdForName(String title) {
136
+
137
+        for(Project_Res project : projects) {
138
+
139
+            if(title.equals(project.getTitle())) {
140
+                return project.getId();
141
+            }
142
+        }
143
+
144
+        return -1;
145
+    }
146
+
147
+    private List<String>  getProjectNames() {
148
+        ArrayList<String> titles = new ArrayList<>();
149
+
150
+        for(Project_Res project : projects) {
151
+            titles.add(project.getTitle());
152
+        }
153
+
154
+        return titles;
155
+    }
156
+}

+ 25
- 0
cs240/record-indexer/src/client/components/downloadModal/SampleImage.java View File

@@ -0,0 +1,25 @@
1
+package client.components.downloadModal;
2
+
3
+import javax.swing.*;
4
+import java.awt.*;
5
+import java.awt.image.BufferedImage;
6
+
7
+
8
+public class SampleImage extends JPanel {
9
+
10
+    BufferedImage image;
11
+
12
+    public SampleImage(BufferedImage image) {
13
+        this.image = image;
14
+    }
15
+
16
+    @Override
17
+    protected void paintComponent(Graphics g) {
18
+        super.paintComponent(g);
19
+        Graphics2D g2 = (Graphics2D)g;
20
+
21
+        g2.scale(0.7, 0.7);
22
+        g2.drawImage(image, 0, 0, null);
23
+    }
24
+
25
+}

+ 52
- 0
cs240/record-indexer/src/client/components/downloadModal/SampleImageModal.java View File

@@ -0,0 +1,52 @@
1
+package client.components.downloadModal;
2
+
3
+import javax.imageio.ImageIO;
4
+import javax.swing.*;
5
+import java.awt.*;
6
+import java.awt.event.ActionEvent;
7
+import java.awt.event.ActionListener;
8
+import java.awt.event.WindowEvent;
9
+import java.awt.image.BufferedImage;
10
+import java.io.File;
11
+import java.io.IOException;
12
+import java.net.URL;
13
+
14
+public class SampleImageModal extends JDialog {
15
+
16
+    BufferedImage image;
17
+
18
+    public SampleImageModal(String path) {
19
+        try {
20
+            image = ImageIO.read(new URL(path));
21
+        } catch (Exception e1) {
22
+            return;
23
+        }
24
+
25
+        setupView();
26
+    }
27
+
28
+    private void setupView() {
29
+        this.setTitle("Sample Image from XXXXXXX");
30
+        this.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
31
+        this.setSize(500, 410);
32
+        this.setResizable(false);
33
+        this.setLocationRelativeTo(null);
34
+
35
+        SampleImage sampleImage = new SampleImage(image);
36
+
37
+        this.add(sampleImage, BorderLayout.CENTER);
38
+
39
+        JButton closeButton = new JButton("Close");
40
+        closeButton.addActionListener(closeListener);
41
+        this.add(closeButton, BorderLayout.SOUTH);
42
+
43
+    }
44
+
45
+    private ActionListener closeListener = new AbstractAction() {
46
+        @Override
47
+        public void actionPerformed(ActionEvent e) {
48
+            setVisible(false);
49
+            dispatchEvent(new WindowEvent(SampleImageModal.this, WindowEvent.WINDOW_CLOSING));
50
+        }
51
+    };
52
+}

+ 77
- 0
cs240/record-indexer/src/client/components/fieldHelp/FieldHelp.java View File

@@ -0,0 +1,77 @@
1
+package client.components.fieldHelp;
2
+
3
+import client.communication.Communicator;
4
+import client.persistence.Cell;
5
+import client.persistence.ImageState;
6
+import client.persistence.ImageStateListener;
7
+import client.persistence.NewProjectListener;
8
+import shared.communication.common.Fields;
9
+
10
+import javax.swing.*;
11
+import java.awt.*;
12
+import java.io.IOException;
13
+
14
+public class FieldHelp extends JPanel {
15
+
16
+    private ImageState imageState;
17
+
18
+    private String[] columns;
19
+    private int currentColumn;
20
+    private JEditorPane editorPane;
21
+    private Communicator communicator;
22
+
23
+    public FieldHelp(ImageState imageState, Communicator communicator) {
24
+        this.imageState = imageState;
25
+        this.communicator = communicator;
26
+
27
+        this.currentColumn = 0;
28
+        this.columns = imageState.getColumnNames();
29
+
30
+        setupView();
31
+
32
+        this.imageState.addListener(imageStateListener);
33
+        this.imageState.addNewProjectListener(newProjectListener);
34
+    }
35
+
36
+    private void setupView() {
37
+        editorPane = new JEditorPane();
38
+        editorPane.setContentType("text/html");
39
+        editorPane.setEditable(false);
40
+
41
+        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
42
+        this.add(new JScrollPane(editorPane), BorderLayout.CENTER);
43
+    }
44
+
45
+    private void updateView() {
46
+        if(!imageState.isHasImage()) return;
47
+
48
+        Fields field = imageState.getFieldsMetaData().get(currentColumn);
49
+        String path = communicator.getServerPath() + field.getHelpUrl();
50
+
51
+        try {
52
+            editorPane.setPage(path);
53
+        } catch (IOException e) {
54
+            e.printStackTrace();
55
+        }
56
+    }
57
+
58
+    private ImageStateListener imageStateListener = new ImageStateListener() {
59
+        @Override
60
+        public void valueChanged(Cell cell, String newValue) {
61
+
62
+        }
63
+
64
+        @Override
65
+        public void selectedCellChanged(Cell newSelectedCell) {
66
+            currentColumn = newSelectedCell.getField();
67
+            updateView();
68
+        }
69
+    };
70
+
71
+    private NewProjectListener newProjectListener = new NewProjectListener() {
72
+        @Override
73
+        public void hasNewProject() {
74
+            editorPane.setText("");
75
+        }
76
+    };
77
+}

+ 141
- 0
cs240/record-indexer/src/client/components/formEntry/FormEntry.java View File

@@ -0,0 +1,141 @@
1
+package client.components.formEntry;
2
+
3
+import client.modules.spellChecker.KnownData;
4
+import client.persistence.*;
5
+
6
+import javax.swing.*;
7
+import javax.swing.event.ListSelectionEvent;
8
+import javax.swing.event.ListSelectionListener;
9
+import java.awt.*;
10
+import java.awt.event.*;
11
+
12
+public class FormEntry extends JPanel {
13
+
14
+    private JList rowNumberList;
15
+    private FormTable formTable;
16
+    private JSplitPane splitPane;
17
+
18
+    private Cell currentCell;
19
+    private String[][] model;
20
+    private String[] columnNames;
21
+    private Integer[] rowIds;
22
+
23
+    private ImageState imageState;
24
+
25
+    public FormEntry(ImageState imageState) {
26
+        this.imageState = imageState;
27
+
28
+        this.model = this.imageState.getModel();
29
+        this.columnNames = this.imageState.getColumnNames();
30
+
31
+        this.imageState.addNewProjectListener(newProjectListener);
32
+
33
+        setupView();
34
+    }
35
+
36
+    private void setupView() {
37
+        this.setLayout(new GridLayout(1,1));
38
+
39
+        this.rowIds = new Integer[model.length];
40
+        generateListData();
41
+
42
+        splitPane = new JSplitPane();
43
+        splitPane.setDividerLocation(50);
44
+        splitPane.setBorder(null);
45
+
46
+        formTable = new FormTable(imageState);
47
+
48
+        splitPane.setRightComponent(new JScrollPane(formTable));
49
+
50
+        rowNumberList = new JList(rowIds);
51
+        rowNumberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
52
+        rowNumberList.setLayoutOrientation(JList.VERTICAL);
53
+        rowNumberList.setVisibleRowCount(-1);
54
+        rowNumberList.addListSelectionListener(listSelectionListener);
55
+        splitPane.setLeftComponent(new JScrollPane(rowNumberList));
56
+
57
+
58
+        this.add(splitPane);
59
+
60
+        imageState.addListener(imageStateListener);
61
+
62
+    }
63
+
64
+    public void generateListData() {
65
+        for(int i = 0; i < rowIds.length; i ++) {
66
+            rowIds[i] = (i+1);
67
+        }
68
+    }
69
+
70
+    @Override
71
+    public Dimension getMinimumSize() {
72
+        Dimension dim = super.getMinimumSize();
73
+        dim.width = 350;
74
+        return dim;
75
+    }
76
+
77
+    private ImageStateListener imageStateListener = new ImageStateListener() {
78
+        @Override
79
+        public void valueChanged(Cell cell, String newValue) {
80
+            int row = cell.getRecord();
81
+            int column = cell.getField();
82
+
83
+            rowNumberList.setSelectedIndex(row);
84
+            formTable.setValue(newValue, row, column);
85
+
86
+            splitPane.repaint();
87
+        }
88
+
89
+        @Override
90
+        public void selectedCellChanged(Cell newSelectedCell) {
91
+            int row = newSelectedCell.getRecord();
92
+            int column = newSelectedCell.getField();
93
+
94
+            currentCell = newSelectedCell;
95
+
96
+            rowNumberList.setSelectedIndex(row);
97
+            formTable.setCurrentCell(row, column);
98
+
99
+            splitPane.repaint();
100
+        }
101
+    };
102
+
103
+    private NewProjectListener newProjectListener = new NewProjectListener() {
104
+        @Override
105
+        public void hasNewProject() {
106
+            model = imageState.getModel();
107
+            columnNames = imageState.getColumnNames();
108
+
109
+            formTable.setDeactivated(true);
110
+            formTable = new FormTable(imageState);
111
+            splitPane.setRightComponent(new JScrollPane(formTable));
112
+
113
+            rowIds = new Integer[model.length];
114
+            generateListData();
115
+            rowNumberList.setListData(rowIds);
116
+        }
117
+    };
118
+
119
+    private ListSelectionListener listSelectionListener = new ListSelectionListener() {
120
+        @Override
121
+        public void valueChanged(ListSelectionEvent e) {
122
+            if(!getParent().getParent().getParent().isVisible()) return;
123
+
124
+            int newRow = rowNumberList.getSelectedIndex();
125
+
126
+            Cell cell = new Cell();
127
+            cell.setRecord(newRow);
128
+            cell.setField(currentCell.getField());
129
+
130
+            imageState.setSelectedCell(cell);
131
+            repaint();
132
+
133
+        }
134
+    };
135
+
136
+    public void becameVisible() {
137
+        formTable.setCurrentCellForce();
138
+    }
139
+
140
+
141
+}

+ 195
- 0
cs240/record-indexer/src/client/components/formEntry/FormTable.java View File

@@ -0,0 +1,195 @@
1
+package client.components.formEntry;
2
+
3
+import client.modules.spellChecker.KnownData;
4
+import client.persistence.Cell;
5
+import client.persistence.ImageState;
6
+
7
+import javax.swing.*;
8
+import java.awt.*;
9
+import java.awt.event.FocusEvent;
10
+import java.awt.event.FocusListener;
11
+
12
+public class FormTable extends JPanel {
13
+
14
+    private String[] fieldNames;
15
+    private String[][] values;
16
+
17
+    private boolean updatingCell;
18
+
19
+    private ImageState imageState;
20
+
21
+    private int currentRow;
22
+    private boolean deactivated = false;
23
+
24
+    public FormTable(ImageState imageState) {
25
+
26
+        this.imageState = imageState;
27
+
28
+        this.fieldNames = this.imageState.getColumnNames();
29
+        this.values = this.imageState.getModel();
30
+
31
+        this.currentRow = 0;
32
+
33
+        setupView();
34
+    }
35
+
36
+    private void setupView() {
37
+        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
38
+
39
+        currentRow = 0;
40
+
41
+        initForm();
42
+
43
+    }
44
+
45
+    private void initForm() {
46
+        for(int i = 0; i < fieldNames.length; i++) {
47
+            String labelString = fieldNames[i];
48
+            String textFieldString = values[currentRow][i];
49
+
50
+            JPanel formContainer = new JPanel();
51
+
52
+            JLabel label = new JLabel(labelString);
53
+            label.setPreferredSize(new Dimension(100,30));
54
+            formContainer.add(label, BorderLayout.WEST);
55
+
56
+            JTextField textField = new JTextField(textFieldString);
57
+            textField.addFocusListener(generateFocusListener(textField, i));
58
+            textField.setPreferredSize(new Dimension(150, 30));
59
+
60
+            if(hasSuggestion(textField.getText(), i)) {
61
+                textField.setBackground(Color.RED);
62
+            }
63
+
64
+            formContainer.add(textField, BorderLayout.CENTER);
65
+
66
+            this.add(formContainer);
67
+        }
68
+    }
69
+
70
+    public void updateCurrentCell(JTextField textField, int index) {
71
+        if(updatingCell || deactivated) return;
72
+
73
+        Cell cell = new Cell();
74
+        cell.setRecord(currentRow);
75
+        cell.setField(index);
76
+
77
+        updatingCell = true;
78
+        imageState.setSelectedCell(cell);
79
+        updatingCell = false;
80
+    }
81
+
82
+    public void updateCellValue(JTextField textField, int index) {
83
+        if(updatingCell || deactivated) return;
84
+
85
+        Cell cell = new Cell();
86
+        cell.setRecord(currentRow);
87
+        cell.setField(index);
88
+
89
+        values[currentRow][index] = textField.getText();
90
+
91
+        if(hasSuggestion(textField.getText(), index)) {
92
+            textField.setBackground(Color.RED);
93
+        } else {
94
+            textField.setBackground(Color.WHITE);
95
+        }
96
+
97
+        updatingCell = true;
98
+        imageState.setValue(cell, textField.getText());
99
+        updatingCell = false;
100
+    }
101
+
102
+    public boolean hasSuggestion(String value, int column) {
103
+        if(value.equals("")) return false;
104
+        KnownData knownData = imageState.getKnownDataValues().get(column);
105
+
106
+        String[] words = knownData.getWordArray();
107
+
108
+        for(String val : words) {
109
+            if(val.toLowerCase().equals(value.toLowerCase())) return false;
110
+        }
111
+
112
+        return true;
113
+    }
114
+
115
+    private FocusListener generateFocusListener(final JTextField textField, final int index) {
116
+        return new FocusListener() {
117
+            @Override
118
+            public void focusGained(FocusEvent e) {
119
+                updateCurrentCell(textField, index);
120
+            }
121
+
122
+            @Override
123
+            public void focusLost(FocusEvent e) {
124
+                updateCellValue(textField, index);
125
+            }
126
+        };
127
+    }
128
+
129
+    private void updateView() {
130
+        if(deactivated) return;
131
+
132
+        updatingCell = true;
133
+        for(int i = 0; i < this.getComponents().length; i++) {
134
+            JPanel formSet = (JPanel)this.getComponent(i);
135
+            JTextField form = (JTextField)formSet.getComponent(1);
136
+            form.setText(values[currentRow][i]);
137
+
138
+            if(hasSuggestion(form.getText(), i)) {
139
+                form.setBackground(Color.RED);
140
+            } else {
141
+                form.setBackground(Color.WHITE);
142
+            }
143
+        }
144
+        updatingCell = false;
145
+    }
146
+
147
+    public void setValue(String newValue, int row, int column) {
148
+        if(updatingCell || deactivated) return;
149
+
150
+        this.updateView();
151
+        this.repaint();
152
+    }
153
+
154
+    public void setCurrentCell(int row, int column) {
155
+        if(updatingCell || deactivated) return;
156
+
157
+        this.currentRow = row;
158
+
159
+        this.updateView();
160
+        this.repaint();
161
+
162
+        this.setFocus(column);
163
+    }
164
+
165
+    public void setCurrentCellForce() {
166
+        if(deactivated) return;
167
+
168
+        final Cell cell = imageState.getSelectedCell();
169
+        SwingUtilities.invokeLater(new Runnable() {
170
+            public void run() {
171
+                setFocus(cell.getField());
172
+            }
173
+        });
174
+    }
175
+
176
+    public void setFocus(int columnField) {
177
+        if(deactivated) return;
178
+
179
+        // offset is x - 1, cause start at 0.
180
+        int column = columnField;
181
+
182
+        if(values.length == 0) return;
183
+
184
+        // get the column textField and request focus
185
+        JPanel formList = (JPanel)this.getComponent(column);
186
+        final JTextField form = (JTextField)formList.getComponent(1);
187
+
188
+        form.requestFocus();
189
+    }
190
+
191
+    public void setDeactivated(boolean deactivated) {
192
+        this.deactivated = deactivated;
193
+    }
194
+
195
+}

+ 45
- 0
cs240/record-indexer/src/client/components/imagePanel/ImageCell.java View File

@@ -0,0 +1,45 @@
1
+package client.components.imagePanel;
2
+
3
+import java.awt.*;
4
+import java.awt.geom.Rectangle2D;
5
+
6
+public class ImageCell {
7
+
8
+    private double x;
9
+    private double y;
10
+    private double width;
11
+    private double height;
12
+    private boolean isSelected;
13
+    Rectangle2D.Double rectangle2D;
14
+
15
+    public ImageCell(Rectangle2D.Double rectangle2D) {
16
+        this.rectangle2D = rectangle2D;
17
+
18
+        this.x = rectangle2D.getBounds2D().getX();
19
+        this.y = rectangle2D.getBounds2D().getY();
20
+        this.width = this.x = rectangle2D.getBounds2D().getWidth();
21
+        this.height = this.x = rectangle2D.getBounds2D().getHeight();
22
+
23
+        this.isSelected = false;
24
+    }
25
+
26
+    public void paint(Graphics2D g2, boolean isSelected) {
27
+        if(isSelected) {
28
+            g2.setColor(new Color(0,119,204, 150));
29
+        } else {
30
+            g2.setColor(new Color(0,0,0, 0));
31
+        }
32
+        g2.fill(rectangle2D);
33
+    }
34
+
35
+    public boolean contains(double x, double y) {
36
+        return rectangle2D.contains(x, y);
37
+    }
38
+
39
+    public double getWidth() {
40
+        return width;
41
+    }
42
+
43
+    public void setWidth(double width) {
44
+        this.width = width;
45
+    }}

+ 174
- 0
cs240/record-indexer/src/client/components/imagePanel/ImageControl.java View File

@@ -0,0 +1,174 @@
1
+package client.components.imagePanel;
2
+
3
+import client.components.imagePanel.listeners.ImageControlsListener;
4
+import client.persistence.ImageState;
5
+import client.persistence.NewProjectListener;
6
+
7
+import javax.swing.*;
8
+import java.awt.*;
9
+import java.awt.event.ActionEvent;
10
+import java.awt.event.ActionListener;
11
+import java.util.ArrayList;
12
+
13
+public class ImageControl extends JPanel {
14
+
15
+    private ArrayList<ImageControlsListener> imageControlsListeners;
16
+
17
+    private ImageState imageState;
18
+
19
+    private JButton zoomInButton;
20
+    private JButton zoomOutButton;
21
+    private JButton invertButton;
22
+    private JButton toggleHighlightsButton;
23
+    private JButton saveButton;
24
+    private JButton submitButton;
25
+
26
+    public ImageControl(ImageState imageState) {
27
+        this.imageState = imageState;
28
+
29
+        this.imageState.addNewProjectListener(newProjectListener);
30
+
31
+        setupView();
32
+
33
+        imageControlsListeners = new ArrayList<>();
34
+    }
35
+
36
+    private void setupView() {
37
+        boolean enabled = false;
38
+
39
+        if(imageState.isHasImage()) enabled = true;
40
+
41
+        zoomInButton = new JButton("Zoom In");
42
+        zoomInButton.addActionListener(zoomInAction);
43
+        zoomInButton.setEnabled(enabled);
44
+        this.add(zoomInButton, BorderLayout.WEST);
45
+
46
+        zoomOutButton = new JButton("Zoom Out");
47
+        zoomOutButton.addActionListener(zoomOutAction);
48
+        zoomOutButton.setEnabled(enabled);
49
+        this.add(zoomOutButton, BorderLayout.WEST);
50
+
51
+        invertButton = new JButton("Invert");
52
+        invertButton.addActionListener(invertImageAction);
53
+        invertButton.setEnabled(enabled);
54
+        this.add(invertButton, BorderLayout.WEST);
55
+
56
+        toggleHighlightsButton = new JButton("Toggle Highlights");
57
+        toggleHighlightsButton.addActionListener(toggleHighlightsAction);
58
+        toggleHighlightsButton.setEnabled(enabled);
59
+        this.add(toggleHighlightsButton, BorderLayout.WEST);
60
+
61
+        saveButton = new JButton("Save");
62
+        saveButton.setEnabled(enabled);
63
+        saveButton.addActionListener(saveAction);
64
+        this.add(saveButton, BorderLayout.WEST);
65
+
66
+        submitButton = new JButton("Submit");
67
+        submitButton.setEnabled(enabled);
68
+        submitButton.addActionListener(submitAction);
69
+        this.add(submitButton, BorderLayout.WEST);
70
+
71
+        this.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
72
+    }
73
+
74
+    @Override
75
+    public Dimension getMaximumSize() {
76
+        Dimension dim = super.getMaximumSize();
77
+        dim.height = 60;
78
+        return dim;
79
+    }
80
+
81
+    public void addControlsListener(ImageControlsListener imageControlsListener) {
82
+        imageControlsListeners.add(imageControlsListener);
83
+    }
84
+
85
+    private void updateZoomInListeners() {
86
+        for(ImageControlsListener cL : imageControlsListeners) {
87
+            cL.onScrollIncrease();
88
+        }
89
+    }
90
+
91
+    private void updateZoomOutListeners() {
92
+        for(ImageControlsListener cL : imageControlsListeners) {
93
+            cL.onScrollDecrease();
94
+        }
95
+    }
96
+
97
+    private void updateInvertImageListeners() {
98
+        for(ImageControlsListener cL : imageControlsListeners) {
99
+            cL.onInvertImage();
100
+        }
101
+    }
102
+
103
+    private void updateToggleHighlightsListeners() {
104
+        for(ImageControlsListener cL : imageControlsListeners) {
105
+            cL.onToggleHighlights();
106
+        }
107
+    }
108
+
109
+    private void updateSaveListeners() {
110
+        imageState.save();
111
+    }
112
+
113
+    private void updateSubmitListeners() {
114
+        imageState.submitProject();
115
+    }
116
+
117
+
118
+    private ActionListener zoomInAction = new AbstractAction() {
119
+        @Override
120
+        public void actionPerformed(ActionEvent e) {
121
+            updateZoomInListeners();
122
+        }
123
+    };
124
+
125
+    private ActionListener zoomOutAction = new AbstractAction() {
126
+        @Override
127
+        public void actionPerformed(ActionEvent e) {
128
+            updateZoomOutListeners();
129
+        }
130
+    };
131
+
132
+    private ActionListener invertImageAction = new AbstractAction() {
133
+        @Override
134
+        public void actionPerformed(ActionEvent e) {
135
+            updateInvertImageListeners();
136
+        }
137
+    };
138
+
139
+    private ActionListener toggleHighlightsAction = new AbstractAction() {
140
+        @Override
141
+        public void actionPerformed(ActionEvent e) {
142
+            updateToggleHighlightsListeners();
143
+        }
144
+    };
145
+
146
+    private ActionListener saveAction = new AbstractAction() {
147
+        @Override
148
+        public void actionPerformed(ActionEvent e) {
149
+            updateSaveListeners();
150
+        }
151
+    };
152
+
153
+    private ActionListener submitAction = new AbstractAction() {
154
+        @Override
155
+        public void actionPerformed(ActionEvent e) {
156
+            updateSubmitListeners();
157
+        }
158
+    };
159
+
160
+    private NewProjectListener newProjectListener = new NewProjectListener() {
161
+        @Override
162
+        public void hasNewProject() {
163
+            boolean status = imageState.isHasImage();
164
+
165
+            zoomInButton.setEnabled(status);
166
+            zoomOutButton.setEnabled(status);
167
+            invertButton.setEnabled(status);
168
+            toggleHighlightsButton.setEnabled(status);
169
+            saveButton.setEnabled(status);
170
+            submitButton.setEnabled(status);
171
+        }
172
+    };
173
+
174
+}

+ 36
- 0
cs240/record-indexer/src/client/components/imagePanel/ImagePanel.java View File

@@ -0,0 +1,36 @@
1
+package client.components.imagePanel;
2
+
3
+import client.components.imagePanel.listeners.ImageControlsListener;
4
+import client.persistence.*;
5
+
6
+import javax.swing.*;
7
+import java.awt.*;
8
+
9
+public class ImagePanel extends JPanel {
10
+
11
+    private ImageControl imageControl;
12
+    private ScalableImage scalableImage;
13
+
14
+    private ImageState imageState;
15
+
16
+    public ImagePanel(ImageState imageState) {
17
+        this.imageState = imageState;
18
+
19
+        setupView();
20
+    }
21
+
22
+    private void setupView() {
23
+        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
24
+        this.setBackground(Color.DARK_GRAY);
25
+
26
+        scalableImage = new ScalableImage(imageState);
27
+        ImageControlsListener imageControlsListener = scalableImage.getImageControlsListener();
28
+
29
+        imageControl = new ImageControl(imageState);
30
+        imageControl.addControlsListener(imageControlsListener);
31
+
32
+        this.add(imageControl, Component.LEFT_ALIGNMENT);
33
+
34
+        this.add(scalableImage, BorderLayout.CENTER);
35
+    }
36
+}

+ 147
- 0
cs240/record-indexer/src/client/components/imagePanel/ImageTable.java View File

@@ -0,0 +1,147 @@
1
+package client.components.imagePanel;
2
+
3
+import client.components.imagePanel.ImageCell;
4
+import client.persistence.Cell;
5
+import client.persistence.ImageState;
6
+import client.persistence.ImageStateListener;
7
+import client.persistence.SyncContext;
8
+
9
+import java.awt.*;
10
+import java.awt.geom.Rectangle2D;
11
+import java.util.ArrayList;
12
+
13
+public class ImageTable {
14
+
15
+    private int recordsPerImage;
16
+    private int firstYCoord;
17
+    private int recordHeight;
18
+    private int columnCount;
19
+
20
+    private ArrayList<Integer> fieldXValues;
21
+    private ArrayList<Integer> fieldWidthValues;
22
+
23
+    private ImageCell[][] model;
24
+
25
+    private Rectangle2D.Double tableBoundaries;
26
+    private boolean highlightsEnabled;
27
+
28
+    private ImageCell currentSelected;
29
+
30
+    private ImageState imageState;
31
+    private boolean deactivated = false;
32
+
33
+    public ImageTable(ImageState imageState) {
34
+
35
+        this.imageState = imageState;
36
+
37
+        this.recordsPerImage = imageState.getRecordsPerImage();
38
+        this.firstYCoord = imageState.getFirstYCoord();
39
+        this.recordHeight = imageState.getRecordHeight();
40
+        this.columnCount = imageState.getColumnCount();
41
+        this.fieldXValues = imageState.getFieldXValues();
42
+        this.fieldWidthValues = imageState.getFieldWidthValues();
43
+
44
+        // Note we go [y][x]
45
+        model = new ImageCell[recordsPerImage][columnCount];
46
+
47
+        highlightsEnabled = imageState.getSettings().isImageHighlights();
48
+
49
+        if(!imageState.isHasImage()) return;
50
+
51
+        generateModel();
52
+        generateTableBoundaries();
53
+    }
54
+
55
+    private void generateModel() {
56
+        for(int y = 0; y < recordsPerImage; y++) {
57
+            for(int x = 0; x < columnCount; x++) {
58
+                Rectangle2D.Double rect = new Rectangle2D.Double();
59
+
60
+                int rectY = firstYCoord + (y * recordHeight); // y starts at 0.
61
+                int rectX = fieldXValues.get(x);
62
+                int width = fieldWidthValues.get(x);
63
+                int height = recordHeight;
64
+
65
+                rect.setRect(rectX, rectY, width, height);
66
+
67
+                model[y][x] = new ImageCell(rect);
68
+            }
69
+        }
70
+    }
71
+
72
+    public void paint(Graphics2D g2) {
73
+        for(int y = 0; y < recordsPerImage; y++) {
74
+            for(int x = 0; x < columnCount; x++) {
75
+                ImageCell imageCell = model[y][x];
76
+
77
+                if(imageCell == currentSelected && highlightsEnabled) {
78
+                    model[y][x].paint(g2, true);
79
+                } else {
80
+                    model[y][x].paint(g2, false);
81
+                }
82
+            }
83
+        }
84
+    }
85
+
86
+    public void contains(int worldX, int worldY) {
87
+        // Make sure in table boundaries first.
88
+        if(!tableBoundaries.contains(worldX, worldY)) {
89
+            return;
90
+        }
91
+
92
+        for(int y = 0; y < recordsPerImage; y++) {
93
+            for(int x = 0; x < columnCount; x++) {
94
+                ImageCell imageCell = model[y][x];
95
+                if(imageCell.contains(worldX, worldY)) {
96
+                    this.currentSelected = imageCell;
97
+                    setCurrentCell(x, y);
98
+
99
+                    Cell cell = new Cell();
100
+                    cell.setField(x);
101
+                    cell.setRecord(y);
102
+                    this.imageState.setSelectedCell(cell);
103
+                }
104
+            }
105
+        }
106
+    }
107
+
108
+    public void setCurrentCell(int x, int y) {
109
+        if(model.length == 0 || deactivated) return;
110
+
111
+        this.currentSelected = model[y][x];
112
+    }
113
+
114
+    private void generateTableBoundaries() {
115
+
116
+        int y = firstYCoord;
117
+        int x = fieldXValues.get(0);
118
+
119
+        int width = 0;
120
+        for(int fw : fieldWidthValues) {
121
+            width += fw;
122
+        }
123
+
124
+        int height = recordsPerImage * recordHeight;
125
+
126
+        tableBoundaries = new Rectangle2D.Double(x, y, width, height);
127
+    }
128
+
129
+    public void enableHighlights(boolean value) {
130
+        this.highlightsEnabled = value;
131
+
132
+        imageState.getSettings().setImageHighlights(value);
133
+    }
134
+
135
+    public boolean isHighlightsEnabled() {
136
+        return highlightsEnabled;
137
+    }
138
+
139
+
140
+    public void setDeactivated(boolean deactivated) {
141
+        this.deactivated = deactivated;
142
+    }
143
+
144
+    public boolean isDeactivated() {
145
+        return deactivated;
146
+    }
147
+}

+ 291
- 0
cs240/record-indexer/src/client/components/imagePanel/ScalableImage.java View File

@@ -0,0 +1,291 @@
1
+package client.components.imagePanel;
2
+
3
+import client.components.imagePanel.listeners.ImageControlsListener;
4
+import client.components.listeners.DrawingListener;
5
+import client.persistence.*;
6
+
7
+import javax.imageio.ImageIO;
8
+import javax.swing.*;
9
+import java.awt.*;
10
+import java.awt.event.MouseAdapter;
11
+import java.awt.event.MouseEvent;
12
+import java.awt.event.MouseWheelEvent;
13
+import java.awt.geom.AffineTransform;
14
+import java.awt.geom.NoninvertibleTransformException;
15
+import java.awt.geom.Point2D;
16
+import java.awt.image.BufferedImage;
17
+import java.io.File;
18
+import java.io.IOException;
19
+import java.util.ArrayList;
20
+
21
+public class ScalableImage extends JPanel {
22
+
23
+    private BufferedImage image;
24
+
25
+    private int w_originX;
26
+    private int w_originY;
27
+    private double scale;
28
+
29
+    private boolean dragging;
30
+    private int w_dragStartX;
31
+    private int w_dragStartY;
32
+    private int w_dragStartOriginX;
33
+    private int w_dragStartOriginY;
34
+
35
+    private ImageTable imageTable;
36
+
37
+    private double MAX_SCROLL = 1.0f;
38
+    private double MIN_SCROLL = 0.2f;
39
+
40
+    private ImageState imageState;
41
+
42
+
43
+    public ScalableImage(ImageState imageState) {
44
+        this.imageState = imageState;
45
+
46
+        this.setBackground(Color.DARK_GRAY);
47
+
48
+        initDrag();
49
+
50
+        this.addMouseListener(mouseAdapter);
51
+        this.addMouseMotionListener(mouseAdapter);
52
+        this.addMouseWheelListener(mouseAdapter);
53
+
54
+        setupView();
55
+
56
+        this.imageState.addListener(imageStateListener);
57
+        this.imageState.addNewProjectListener(newProjectListener);
58
+
59
+    }
60
+
61
+    private void setupView() {
62
+        image = imageState.getImage();
63
+
64
+        imageTable = new ImageTable(imageState);
65
+
66
+        this.setOrigin(imageState.getSettings().getImageOriginX(),
67
+                imageState.getSettings().getImageOriginY());
68
+
69
+        this.setScale(imageState.getSettings().getImageScaleLevel());
70
+
71
+        this.repaint();
72
+    }
73
+
74
+    public void refreshImage() {
75
+        imageTable.setDeactivated(true);
76
+        setupView();
77
+    }
78
+
79
+    boolean redrawHack = false;
80
+
81
+    @Override
82
+    protected void paintComponent(Graphics g) {
83
+        super.paintComponent(g);
84
+
85
+        Graphics2D g2 = (Graphics2D)g;
86
+
87
+        g2.translate(this.getWidth() / 2, this.getHeight() / 2);
88
+        g2.scale(scale, scale);
89
+        g2.translate(-w_originX, -w_originY);
90
+        g2.drawImage(image, 0, 0, null);
91
+
92
+        imageTable.paint(g2);
93
+
94
+        if(!redrawHack) {
95
+            redrawHack = true;
96
+            this.repaint();
97
+        }
98
+    }
99
+
100
+    public void invertImage(BufferedImage b) {
101
+        for (int x = 0; x < b.getWidth(); x++) {
102
+            for (int y = 0; y < b.getHeight(); y++) {
103
+                int rgba = b.getRGB(x, y);
104
+                Color col = new Color(rgba, true);
105
+                col = new Color(255 - col.getRed(),
106
+                        255 - col.getGreen(),
107
+                        255 - col.getBlue());
108
+                b.setRGB(x, y, col.getRGB());
109