├── .gitignore
├── JSONsimple
├── .gitkeep
└── json-simple-1.1.1.jar
├── JavaFX
├── .gitkeep
└── lib
│ ├── .gitkeep
│ ├── javafx-swt.jar
│ ├── javafx.base.jar
│ ├── javafx.controls.jar
│ ├── javafx.fxml.jar
│ ├── javafx.graphics.jar
│ ├── javafx.media.jar
│ ├── javafx.properties
│ ├── javafx.swing.jar
│ ├── javafx.web.jar
│ └── src.zip
├── README.md
├── input.json
├── out
└── production
│ └── project-13-design
│ ├── JavaFxApplication.iml
│ ├── META-INF
│ └── project-13-design.kotlin_module
│ └── sample
│ ├── main.css
│ └── main.html
├── project-13-design.iml
└── src
├── JavaFxApplication.iml
├── controllers
├── AlertHelper.java
├── MainController.java
├── ProjectOverviewController.java
├── ProjectScheduleController.java
├── dashboardController.java
├── editMemberController.java
├── milestonesController.java
├── newMemberController.java
├── riskMatrixController.java
└── userInfoController.java
├── fxml-files
├── contactUs.fxml
├── dashboard.fxml
├── editMember.fxml
├── milestones.fxml
├── newMember.fxml
├── projectOverview.fxml
├── projectSchedule.fxml
├── riskMatrix.fxml
└── userInfo.fxml
├── id_generator
└── GeneratorMain.java
├── json_reader_writer
├── JsonReader.java
└── JsonWriter.java
├── member_manager
├── Member.java
├── Milestone.java
├── Planner.java
├── RiskMatrix.java
├── Schedule.java
└── Timesheet.java
└── sample
├── Main.java
└── main.css
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | /out/
3 | .out/
4 | *.iml
5 | /test.json
--------------------------------------------------------------------------------
/JSONsimple/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JSONsimple/.gitkeep
--------------------------------------------------------------------------------
/JSONsimple/json-simple-1.1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JSONsimple/json-simple-1.1.1.jar
--------------------------------------------------------------------------------
/JavaFX/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/.gitkeep
--------------------------------------------------------------------------------
/JavaFX/lib/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/.gitkeep
--------------------------------------------------------------------------------
/JavaFX/lib/javafx-swt.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx-swt.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.base.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.base.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.controls.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.controls.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.fxml.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.fxml.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.graphics.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.graphics.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.media.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.media.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.properties:
--------------------------------------------------------------------------------
1 | javafx.version=11.0.2
2 | javafx.runtime.version=11.0.2+1
3 | javafx.runtime.build=1
4 |
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.swing.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.swing.jar
--------------------------------------------------------------------------------
/JavaFX/lib/javafx.web.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/javafx.web.jar
--------------------------------------------------------------------------------
/JavaFX/lib/src.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brother-Blue/JavaFX-group-management-app/ca9ada5a768e3302891834161f2053e5c6326775/JavaFX/lib/src.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Project description
2 | Software tool to manage a software project.
3 | * Use data from our project.
4 | * The demo should be pre-loaded with actual data generated during the development of the project itself.
5 | * (input file) will be specified/stored via a JSON file or any other convenient format/technology.
6 | * The structure and content of the input is up to the imagination of the project group.
7 | * Each project group member should have a unique number (i.e., member ID) to be used in search functionality.
8 |
9 | # Features
10 | * [ ] Earned Value (EV)should be calculated at intervals of 2 weeks.
11 | * [ ] Schedule Variance (SV)should be calculated at intervals of 2 weeks.
12 | * [ ] Cost Variance (CV)should be calculated at intervals of 2 weeks.
13 | * [ ] Risk Matrixshould indicate the risk = impact x likelihood.
14 | * [ ] Project Scheduleindicating activity, start week and end week.
15 | * [ ] Time spent on the project per team member.
16 | * [ ] The system should be able to search by team member to show the time spent by the member.
17 | * [ ] The system should be able to search by team member to show the work products where (s)he has participated.
18 |
19 | # Other files
20 | [Trello](https://trello.com/b/e9JXYcHB/group-13)
21 | [Time spent](https://docs.google.com/spreadsheets/d/11prYMzwm3u-r01q-JYTA9KiewqtteWdSsmUbRfXNwww/edit#gid=634347005)
22 | [Role description](https://docs.google.com/document/d/195QX52F8_163NgF6ZDA371yS6VPNdnxj2ce9t3elpsw/edit)
23 | [Role schedule](https://docs.google.com/spreadsheets/d/11prYMzwm3u-r01q-JYTA9KiewqtteWdSsmUbRfXNwww/edit#gid=1063704)
24 | # Authors
25 | * Altug Altetmek
26 | * Christian O'Neil
27 | * Clementne Jensen
28 | * Hjalmar Thunberg
29 | * Hugo Hempel
30 | * Linus Ivarsson
31 | * Linus Åberg
32 |
33 |
--------------------------------------------------------------------------------
/input.json:
--------------------------------------------------------------------------------
1 |
2 |
3 | {
4 | "endDate": "2020-01-10",
5 | "members": [
6 | {
7 | "firstName": "Hjalmar",
8 | "lastName": "Thunberg",
9 | "ID": "18619",
10 | "salary": "250.0"
11 | },
12 | {
13 | "firstName": "Altug",
14 | "lastName": "Altetmek",
15 | "ID": "14587",
16 | "salary": "210.0"
17 | },
18 | {
19 | "firstName": "Christian",
20 | "lastName": "O'Neill",
21 | "ID": "23787",
22 | "salary": "145.0"
23 | },
24 | {
25 | "firstName": "Clementine",
26 | "lastName": "Jensen",
27 | "ID": "26162",
28 | "salary": "220.0"
29 | },
30 | {
31 | "firstName": "Hugo",
32 | "lastName": "Hempel",
33 | "ID": "13209",
34 | "salary": "250.0"
35 | },
36 | {
37 | "firstName": "Linus",
38 | "lastName": "Ivarsson",
39 | "ID": "14975",
40 | "salary": "150.0"
41 | },
42 | {
43 | "firstName": "Linus",
44 | "lastName": "Åberg",
45 | "ID": "17004",
46 | "salary": "280.0"
47 | }
48 | ],
49 | "riskMatrix": [
50 | {
51 | "riskName": "Json files become corrupted \nand all data is lost",
52 | "unlikely": "Severe",
53 | "veryLikely": "Catastrophic",
54 | "possible": "Catastrophic"
55 | },
56 | {
57 | "riskName": "Developer corrupts the \ndata on purpose",
58 | "unlikely": "Moderate",
59 | "veryLikely": "Catastrophic",
60 | "possible": "Catastrophic"
61 | },
62 | {
63 | "riskName": "Software not matching \nthe requirements",
64 | "unlikely": "Moderate",
65 | "veryLikely": "Catastrophic",
66 | "possible": "Severe"
67 | },
68 | {
69 | "riskName": "User finds the UI \ncomplicated to use",
70 | "unlikely": "Low",
71 | "veryLikely": "Catastrophic",
72 | "possible": "Moderate"
73 | },
74 | {
75 | "riskName": "Developer dies",
76 | "unlikely": "Low",
77 | "veryLikely": "Catastrophic",
78 | "possible": "Moderate"
79 | },
80 | {
81 | "riskName": "Bugs after release",
82 | "unlikely": "Moderate",
83 | "veryLikely": "Severe",
84 | "possible": "Severe"
85 | },
86 | {
87 | "riskName": "GitLab crashes and team can’t function in a collaborative way",
88 | "unlikely": "Moderate",
89 | "veryLikely": "Severe",
90 | "possible": "Severe"
91 | },
92 | {
93 | "riskName": "Hardware malfunction",
94 | "unlikely": "Low",
95 | "veryLikely": "Severe",
96 | "possible": "Moderate"
97 | },
98 | {
99 | "riskName": "Miscommunication between developers",
100 | "unlikely": "Low",
101 | "veryLikely": "Severe",
102 | "possible": "Moderate"
103 | },
104 | {
105 | "riskName": "Developer drops out",
106 | "unlikely": "Low",
107 | "veryLikely": "Severe",
108 | "possible": "Moderate"
109 | },
110 | {
111 | "riskName": "User does not understand the language of the software",
112 | "unlikely": "Low",
113 | "veryLikely": "Moderate",
114 | "possible": "Low"
115 | }
116 | ],
117 | "projectName": "Project 13",
118 | "timesheet": [
119 | {
120 | "week": "1",
121 | "hoursWorked": {
122 | "26162": "11",
123 | "17004": "4",
124 | "13209": "4",
125 | "14587": "2",
126 | "18619": "8",
127 | "23787": "7",
128 | "14975": "5"
129 | },
130 | "percentComplete" : "0.05"
131 | },
132 | {
133 | "week": "2",
134 | "hoursWorked": {
135 | "26162": "17",
136 | "17004": "1",
137 | "13209": "2",
138 | "14587": "11",
139 | "18619": "12",
140 | "23787": "12",
141 | "14975": "2"
142 | },
143 | "percentComplete" : "0.11"
144 | },
145 | {
146 | "week": "3",
147 | "hoursWorked": {
148 | "26162": "17",
149 | "17004": "20",
150 | "13209": "12",
151 | "14587": "14",
152 | "18619": "15",
153 | "23787": "11",
154 | "14975": "20"
155 | },
156 | "percentComplete" : "0.18"
157 | },
158 | {
159 | "week": "4",
160 | "hoursWorked": {
161 | "26162": "2",
162 | "17004": "14",
163 | "13209": "4",
164 | "14587": "1",
165 | "18619": "4",
166 | "23787": "27",
167 | "14975": "23"
168 | },
169 | "percentComplete" : "0.41"
170 | },
171 | {
172 | "week": "5",
173 | "hoursWorked": {
174 | "26162": "0",
175 | "17004": "0",
176 | "13209": "0",
177 | "14587": "0",
178 | "18619": "0",
179 | "23787": "8",
180 | "14975": "0"
181 | },
182 | "percentComplete" : "0.64"
183 | },
184 | {
185 | "week": "6",
186 | "hoursWorked": {
187 | "26162": "0",
188 | "17004": "0",
189 | "13209": "0",
190 | "14587": "0",
191 | "18619": "0",
192 | "23787": "2",
193 | "14975": "0"
194 | },
195 | "percentComplete" : "0.85"
196 | },
197 | {
198 | "week": "7",
199 | "hoursWorked": {
200 | "26162": "0",
201 | "17004": "0",
202 | "13209": "0",
203 | "14587": "0",
204 | "18619": "0",
205 | "23787": "0",
206 | "14975": "0"
207 | },
208 | "percentComplete" : "0.87"
209 | },
210 | {
211 | "week": "8",
212 | "hoursWorked": {
213 | "26162": "0",
214 | "17004": "0",
215 | "13209": "0",
216 | "14587": "0",
217 | "18619": "0",
218 | "23787": "7",
219 | "14975": "0"
220 | },
221 | "percentComplete" : "0.89"
222 | },
223 | {
224 | "week": "9",
225 | "hoursWorked": {
226 | "26162": "0",
227 | "17004": "0",
228 | "13209": "0",
229 | "14587": "0",
230 | "18619": "0",
231 | "23787": "0",
232 | "14975": "0"
233 | },
234 | "percentComplete" : "0.0"
235 | },
236 | {
237 | "week": "10",
238 | "hoursWorked": {
239 | "26162": "0",
240 | "17004": "0",
241 | "13209": "0",
242 | "14587": "0",
243 | "18619": "0",
244 | "23787": "0",
245 | "14975": "0"
246 | },
247 | "percentComplete" : "1.0"
248 | }
249 | ],
250 | "milestones": [
251 | {
252 | "actualEndDate": "2019-11-14",
253 | "milestoneName": "Planning Meetings",
254 | "milestoneDescription": "Group got together and planned the week",
255 | "startDate": "2019-11-11",
256 | "plannedEndDate": "2019-11-15",
257 | "hoursPerMember": {
258 | "26162": "3.0",
259 | "17004": "3.0",
260 | "13209": "3.0",
261 | "14587": "3.0",
262 | "18619": "3.0",
263 | "23787": "3.0",
264 | "14975": "3.0"
265 | }
266 | },
267 | {
268 | "actualEndDate": "2019-12-22",
269 | "milestoneName": "Create FXML files",
270 | "milestoneDescription": "Create and complete all FXML files",
271 | "startDate": "2019-11-22",
272 | "plannedEndDate": "2019-11-15",
273 | "hoursPerMember": {
274 | "26162": "19.0",
275 | "17004": "0.0",
276 | "13209": "10.0",
277 | "14587": "0.0",
278 | "18619": "0.0",
279 | "23787": "9.0",
280 | "14975": "16.0"
281 | }
282 | },
283 | {
284 | "actualEndDate": "2019-11-15",
285 | "milestoneName": "Class diagram",
286 | "milestoneDescription": "Creating a complete class diagram over our software",
287 | "startDate": "2019-11-13",
288 | "plannedEndDate": "2019-11-15",
289 | "hoursPerMember": {
290 | "26162": "2.0",
291 | "17004": "0.0",
292 | "13209": "0.0",
293 | "14587": "0.0",
294 | "18619": "3.0",
295 | "23787": "8.0",
296 | "14975": "2.0"
297 | }
298 | },
299 | {
300 | "actualEndDate": "2019-12-22",
301 | "milestoneName": "Create Controllers",
302 | "milestoneDescription": "Creating all controllers classes for our interface",
303 | "startDate": "2019-11-22",
304 | "plannedEndDate": "2019-11-27",
305 | "hoursPerMember": {
306 | "26162": "18.0",
307 | "17004": "0.0",
308 | "13209": "10.0",
309 | "14587": "0.0",
310 | "18619": "0.0",
311 | "23787": "18.0",
312 | "14975": "18.0"
313 | }
314 | },
315 | {
316 | "actualEndDate": "2020-01-10",
317 | "milestoneName": "Develop methods",
318 | "milestoneDescription": "Complete all methods for the software",
319 | "startDate": "2019-11-18",
320 | "plannedEndDate": "2020-01-10",
321 | "hoursPerMember": {
322 | "26162": "10.0",
323 | "17004": "18.0",
324 | "13209": "11.0",
325 | "14587": "10.0",
326 | "18619": "17.0",
327 | "23787": "14.0",
328 | "14975": "8.0"
329 | }
330 | },
331 | {
332 | "actualEndDate": "2019-12-22",
333 | "milestoneName": "Implement JSON",
334 | "milestoneDescription": "Create JSON reader, writer and input files",
335 | "startDate": "2019-11-25",
336 | "plannedEndDate": "2019-11-15",
337 | "hoursPerMember": {
338 | "26162": "0.0",
339 | "17004": "14.0",
340 | "13209": "0.0",
341 | "14587": "20.0",
342 | "18619": "17.0",
343 | "23787": "5.0",
344 | "14975": "4.0"
345 | }
346 | },
347 | {
348 | "actualEndDate": "2020-01-09",
349 | "milestoneName": "Finish coding",
350 | "milestoneDescription": "Complete the entire code for the entire software",
351 | "startDate": "2019-11-25",
352 | "plannedEndDate": "2019-01-10",
353 | "hoursPerMember": {
354 | "26162": "6.0",
355 | "17004": "14.0",
356 | "13209": "11.0",
357 | "14587": "15.0",
358 | "18619": "10.0",
359 | "23787": "16.0",
360 | "14975": "8.0"
361 | }
362 | },
363 | {
364 | "actualEndDate": "2020-01-10",
365 | "milestoneName": "Final report",
366 | "milestoneDescription": "Write the final report for our course",
367 | "startDate": "2019-12-17",
368 | "plannedEndDate": "2020-01-17",
369 | "hoursPerMember": {
370 | "26162": "8.0",
371 | "17004": "8.0",
372 | "13209": "8.0",
373 | "14587": "8.0",
374 | "18619": "8.0",
375 | "23787": "8.0",
376 | "14975": "8.0"
377 | }
378 | },
379 | {
380 | "actualEndDate": "2020-01-10",
381 | "milestoneName": "Create executable",
382 | "milestoneDescription": "Create a executable program of our software",
383 | "startDate": "2019-12-17",
384 | "plannedEndDate": "2020-01-10",
385 | "hoursPerMember": {
386 | "26162": "0.0",
387 | "17004": "4.0",
388 | "13209": "0.0",
389 | "14587": "0.0",
390 | "18619": "0.0",
391 | "23787": "0.0",
392 | "14975": "0.0"
393 | }
394 | },
395 | {
396 | "actualEndDate": "2019-12-01",
397 | "milestoneName": "Migration to JavaFX",
398 | "milestoneDescription": "Move our Java based project to a new one and migrate it to JavaFX",
399 | "startDate": "2019-11-18",
400 | "plannedEndDate": "2019-11-29",
401 | "hoursPerMember": {
402 | "26162": "6.0",
403 | "17004": "0.0",
404 | "13209": "0.0",
405 | "14587": "0.0",
406 | "18619": "0.0",
407 | "23787": "1.0",
408 | "14975": "1.0"
409 | }
410 | }
411 | ],
412 | "startDate": "2019-11-08",
413 | "budget": "43000.0"
414 | }
415 |
416 |
--------------------------------------------------------------------------------
/out/production/project-13-design/JavaFxApplication.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/out/production/project-13-design/META-INF/project-13-design.kotlin_module:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/out/production/project-13-design/sample/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | height: 100%;
3 | width: 100%;
4 | background-image: linear-gradient(to bottom right, #b4b4b4, #4bb4bb);
5 | background-repeat: no-repeat;
6 | }
7 |
8 | .main-bar {
9 | font-size: 3em;
10 | color: #3e3e3e;
11 | text-shadow: 3px 2px 5px #4bb4bb;
12 | float: left;
13 | padding-bottom: 25px;
14 | margin-bottom: 30px;
15 | }
16 |
17 | .id-search-bar {
18 | float: left;
19 | padding-top: 50px;
20 | }
21 |
22 | .about-member {
23 | float: right;
24 | padding-top: 50px;
25 | }
26 |
27 | * {
28 | box-sizing: border-box;
29 | }
30 |
31 | form.id-search-form input[type=text]{
32 | padding: 10px;
33 | font-size: 15px;
34 | border: 1px solid gray;
35 | float: left;
36 | width: 40%;
37 | background: #b4b4b4;
38 | }
39 |
40 | form.id-search-form button {
41 | float: left;
42 | padding: 10px;
43 | background: #4bb4bb;
44 | color: white;
45 | border: 1px solid gray;
46 | border-left: none;
47 | cursor: pointer;
48 | }
49 |
50 | form.id-search-form button:hover {
51 | background-color: #44a4aa;
52 | }
53 |
54 | form.id-search-form::after {
55 | content: "";
56 | clear: both;
57 | display: table;
58 | }
59 |
60 | .member-table-display {
61 | width: 80%;
62 | box-shadow: 8px 8px 3px rgba(0, 0, 0, 0.25);
63 | }
64 |
65 | .about-member {
66 | padding-right: 20px;
67 | height: 450px;
68 | overflow: auto;
69 | box-shadow: -8px 8px 3px rgba(0, 0, 0, 0.25);
70 | }
71 |
72 | .personIcon {
73 | width: 100px;
74 | }
75 |
76 | .search-bar-dropdown {
77 | padding: 0;
78 | margin-bottom: 35px;
79 | width: 80%;
80 | background: #4bb4bb;
81 | border-top: none;
82 | box-shadow: 2px 2px 1px rgba(0, 0, 0, 0.25);
83 | }
84 |
85 | .search-bar-dropdown button {
86 | width: 100%;
87 | text-align: center;
88 | padding: 5px;
89 | color: white;
90 | border: 1px solid gray;
91 | border-top: none;
92 | }
93 |
94 | .dropdown-menu {
95 | border-bottom: 2px solid #bbbbbb;
96 | }
--------------------------------------------------------------------------------
/out/production/project-13-design/sample/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Group 13 Project
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | G.13 Project Manager
18 |
19 |
20 |
21 |
27 |
28 |
29 | Dropdown
30 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Member Info
47 |
48 |
49 |
50 |
51 | Member ID: #Replace this with the get member ID#
52 |
53 |
54 | Name: #Replace this with the get member name#
55 |
56 |
57 | Nickname: #Replace this with the get member nickname#
58 |
59 |
60 |
61 |
62 |
63 |
64 | Compare #Member#
65 |
66 |
67 |
68 |
69 | Compare hourly pay
70 | Compare
71 |
72 |
73 | Compare hourly pay against
74 | Dropdown
75 |
76 |
77 | Compare hours worked
78 | Compare
79 |
80 |
81 | Compare hours worked against
82 | Dropdown
83 |
84 |
85 | Compare total salary
86 | Compare
87 |
88 |
89 | Compare total salary against
90 | Dropdown
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
106 |
107 |
--------------------------------------------------------------------------------
/project-13-design.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/JavaFxApplication.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/controllers/AlertHelper.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.scene.control.Alert;
4 | import javafx.stage.Window;
5 |
6 | public class AlertHelper {
7 |
8 | public static void showAlert(Alert.AlertType alertType, Window owner, String title, String message) {
9 | Alert alert = new Alert(alertType);
10 | alert.setTitle(title);
11 | alert.setHeaderText(null);
12 | alert.setContentText(message);
13 | alert.initOwner(owner);
14 | alert.show();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/controllers/MainController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import id_generator.GeneratorMain;
4 | import javafx.scene.chart.*;
5 | import javafx.scene.control.*;
6 | import javafx.scene.text.Text;
7 | import json_reader_writer.JsonReader;
8 | import member_manager.Member;
9 | import member_manager.Milestone;
10 | import member_manager.Planner;
11 | import javafx.collections.FXCollections;
12 | import javafx.collections.ObservableList;
13 | import javafx.event.ActionEvent;
14 | import javafx.fxml.FXML;
15 | import javafx.fxml.FXMLLoader;
16 | import javafx.scene.Node;
17 | import javafx.scene.Parent;
18 | import javafx.scene.Scene;
19 | import javafx.stage.Stage;
20 | import javafx.stage.Window;
21 |
22 | import java.io.IOException;
23 | import java.util.ArrayList;
24 |
25 | public class MainController {
26 |
27 | static Planner planner;
28 |
29 | // This code is for all back buttons that go back to the dashboard.
30 | @FXML
31 | public void back(ActionEvent event) throws IOException {
32 |
33 | Parent backMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/dashboard.fxml"));
34 | Scene backMemberScene = new Scene(backMemberParent);
35 |
36 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
37 |
38 | window.setScene(backMemberScene);
39 | window.show();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/controllers/ProjectOverviewController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.beans.property.ObjectProperty;
4 | import javafx.collections.FXCollections;
5 | import javafx.collections.ObservableList;
6 | import javafx.event.ActionEvent;
7 | import javafx.fxml.FXML;
8 | import javafx.fxml.FXMLLoader;
9 | import javafx.fxml.Initializable;
10 | import javafx.scene.Node;
11 | import javafx.scene.Parent;
12 | import javafx.scene.Scene;
13 | import javafx.scene.chart.*;
14 | import javafx.scene.control.*;
15 | import javafx.stage.Stage;
16 | import javafx.stage.Window;
17 | import javafx.util.Duration;
18 | import member_manager.Member;
19 |
20 | import java.io.IOException;
21 | import java.net.URL;
22 | import java.util.ArrayList;
23 | import java.util.ResourceBundle;
24 |
25 | public class ProjectOverviewController extends MainController implements Initializable {
26 |
27 | @FXML
28 | private ComboBox calculatorDropdown;
29 | @FXML
30 | private ComboBox weekSelectionDropdown;
31 | @FXML
32 | private TextField calcResult;
33 | @FXML
34 | private TextArea calcFormula;
35 | @FXML
36 | private TextArea calcDescrip;
37 | @FXML
38 | private AreaChart areaChart;
39 | @FXML
40 | private CategoryAxis xAxis;
41 | @FXML
42 | private NumberAxis yAxis;
43 | @FXML
44 | private Button searchButton;
45 |
46 | private int weekSelected = 1;
47 |
48 | public void riskMatrixView(ActionEvent event) throws IOException {
49 | Parent riskMatrixMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/riskMatrix.fxml"));
50 | Scene riskMatrixMemberScene = new Scene(riskMatrixMemberParent);
51 |
52 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
53 |
54 | window.setScene(riskMatrixMemberScene);
55 | window.show();
56 | }
57 |
58 | public void projectScheduleView(ActionEvent event) throws IOException{
59 | Parent projectScheduleParent = FXMLLoader.load(getClass().getResource("../fxml-files/projectSchedule.fxml"));
60 | Scene projectScheduleScene = new Scene(projectScheduleParent);
61 |
62 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
63 |
64 | window.setScene(projectScheduleScene);
65 | window.show();
66 | }
67 |
68 | public void weekSelected() {
69 | weekSelected = Integer.parseInt(weekSelectionDropdown.getValue().toString().substring(5));
70 | calcSelection();
71 | }
72 |
73 | @Override
74 | public void initialize(URL url, ResourceBundle resourceBundle) {
75 |
76 | ObservableList calcOptions = FXCollections.observableArrayList();
77 | calcOptions.addAll("Planned Value (PV)", "Earned Value (EV)", "Actual Cost (AC)",
78 | "Budget at Completion (BAC)", "Schedule Variance (SV)",
79 | "Schedule Performance Index (SPI)", "Cost Variance (CV)",
80 | "Cost Performance Index (CPI)");
81 |
82 | ObservableList weekOptions = FXCollections.observableArrayList();
83 | weekOptions.addAll("Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6", "Week 7", "Week 8", "Week 9");
84 |
85 | weekSelectionDropdown.setItems(weekOptions);
86 | calculatorDropdown.setItems(calcOptions);
87 |
88 | xAxis.setAnimated(false);
89 | yAxis.setAnimated(false);
90 | }
91 |
92 | public void calcSelection() {
93 | Window owner = calculatorDropdown.getScene().getWindow();
94 | String selection = calculatorDropdown.getValue().toString();
95 |
96 | if (selection == null){
97 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Please select an option");
98 | } else if (selection == "Planned Value (PV)"){
99 | plannedValue();
100 | } else if (selection == "Earned Value (EV)"){
101 | earnedValue();
102 | } else if (selection == "Actual Cost (AC)") {
103 | actualCost();
104 | } else if (selection == "Budget at Completion (BAC)") {
105 | budgetAtCompl();
106 | } else if (selection == "Schedule Variance (SV)") {
107 | scheduleVariance();
108 | } else if (selection == "Schedule Performance Index (SPI)") {
109 | schedulePerfIndex();
110 | } else if (selection == "Cost Variance (CV)") {
111 | costVariance();
112 | } else if (selection == "Cost Performance Index (CPI)"){
113 | costPerfIndex();
114 | }
115 | }
116 |
117 | public void plannedValue(){
118 | searchButton.setDisable(true);
119 | ArrayList results = planner.calcPv();
120 | XYChart.Series pvSeries = new XYChart.Series();
121 | areaChart.getData().clear();
122 |
123 | calcDescrip.setText("Planned value is the relation between the amount of days a current milestone has been worked on and the current budget. " +
124 | "The current days are measured from when the milestone started up to the current day."); //calcWeek - 1 brings the graph value thats displayed ti the correct value.
125 | calcResult.setText("Current week: " + weekSelected + ", Planned Value: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
126 | calcFormula.setText("Planned Value = Days worked / Total days worked (Expected)");
127 |
128 | pvSeries.setName("PV Values");
129 | xAxis.setLabel("Week");
130 | yAxis.setLabel("Amount (SEK)");
131 |
132 | for (int i = 0; i < results.size(); i++) {
133 | pvSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
134 | }
135 | areaChart.getData().add(pvSeries);
136 | }
137 | public void earnedValue(){
138 | ArrayList results = planner.calcEv();
139 | searchButton.setDisable(true);
140 | XYChart.Series evSeries = new XYChart.Series();
141 | areaChart.getData().clear();
142 |
143 | calcDescrip.setText("Expenditures that should have been realised given the actual technical project progress (based on\n" +
144 | "the expenditure plan) (From lecture slides)");
145 | calcResult.setText("Current week: " + weekSelected + ", Earned Value: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
146 | calcFormula.setText("Percentage of Project Complete * Project Budget");
147 |
148 | evSeries.setName("Earned Value");
149 | xAxis.setLabel("Week");
150 | yAxis.setLabel("Amount (SEK)");
151 |
152 | for (int i = 0; i < results.size(); i++) {
153 | evSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
154 | }
155 |
156 | areaChart.getData().add(evSeries);
157 |
158 | }
159 | public void actualCost(){
160 | ArrayList results = planner.calcActualCost();
161 | searchButton.setDisable(true);
162 | XYChart.Series acSeries = new XYChart.Series();
163 | areaChart.getData().clear();
164 |
165 | double actual = 0;
166 | for (int i = 0; i < results.size(); i++) {
167 | actual = actual + results.get(i);
168 | }
169 |
170 | calcDescrip.setText("Actual Cost is how much was paid at a certain period of time. \n(In our case costs is only salary).\nTotal final costs: " + actual + "sek");
171 | calcResult.setText("Current week: " + weekSelected + ", Actual Cost: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
172 | calcFormula.setText("Actual Cost = Budget - Costs.");
173 |
174 | acSeries.setName("Actual Costs");
175 | xAxis.setLabel("Week");
176 | yAxis.setLabel("Amount (SEK)");
177 |
178 | for (int i = 0; i < results.size(); i++) {
179 | acSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
180 | }
181 |
182 | areaChart.getData().add(acSeries);
183 |
184 | }
185 | public void budgetAtCompl(){
186 | ArrayList results = planner.calcBAC();
187 | searchButton.setDisable(true);
188 | XYChart.Series bacSeries = new XYChart.Series();
189 | areaChart.getData().clear();
190 |
191 | calcDescrip.setText("Shows the current budget at the completion of every work week");
192 | calcResult.setText("Current week: " + weekSelected + ", BAC: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
193 | calcFormula.setText("Current Budget - Weekly Costs");
194 |
195 | bacSeries.setName("Budget at Completion - (Week)");
196 | xAxis.setLabel("Week");
197 | yAxis.setLabel("Amount (SEK)");
198 |
199 | for (int i = 0; i < results.size(); i++) {
200 | bacSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
201 | }
202 |
203 | areaChart.getData().add(bacSeries);
204 | }
205 | public void scheduleVariance(){
206 | ArrayList results = planner.calcSv();
207 | searchButton.setDisable(true);
208 | XYChart.Series svSeries = new XYChart.Series();
209 | areaChart.getData().clear();
210 |
211 | calcDescrip.setText("Difference between planned expenditures and earned value (From lecture slides)");
212 | calcResult.setText("Current week: " + weekSelected + ", Schedule Variance: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
213 | calcFormula.setText("EV – PV");
214 |
215 | svSeries.setName("Scheduled Variance");
216 | xAxis.setLabel("Week");
217 | yAxis.setLabel("Amount (SEK)");
218 |
219 | for (int i = 0; i < results.size(); i++) {
220 | svSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
221 | System.out.println(results.get(i));
222 | }
223 |
224 | areaChart.getData().add(svSeries);
225 |
226 | }
227 | public void schedulePerfIndex(){
228 | ArrayList results = planner.calcSPI();
229 | searchButton.setDisable(true);
230 | XYChart.Series spiSeries = new XYChart.Series();
231 | areaChart.getData().clear();
232 |
233 | calcDescrip.setText("The ratio of Earned Value (EV) over Planned Value (PV)");
234 | calcResult.setText("Current week: " + weekSelected + ", SPI: " + Math.round(results.get(Integer.valueOf(weekSelected)-1)*100.0000)/100.0000);
235 | calcFormula.setText("(EV / PV)*100");
236 |
237 | spiSeries.setName("Scheduled Performance Index");
238 | xAxis.setLabel("Week");
239 | yAxis.setLabel("Index");
240 |
241 | for (int i = 0; i < results.size(); i++) {
242 | spiSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
243 | }
244 |
245 | areaChart.getData().add(spiSeries);
246 | }
247 | public void costVariance(){
248 | ArrayList results = planner.calcCv();
249 | searchButton.setDisable(true);
250 | XYChart.Series cvSeries = new XYChart.Series();
251 | areaChart.getData().clear();
252 |
253 | calcDescrip.setText("Difference between actual expenditures and earned value (From lecture slides)");
254 | calcResult.setText("Current week: " + weekSelected + ", Cost Variance: " + results.get(Integer.valueOf(weekSelected)-1) + "SEK\n");
255 | calcFormula.setText("EV – AV");
256 |
257 | cvSeries.setName("Cost Variance");
258 | xAxis.setLabel("Week");
259 | yAxis.setLabel("Amount (SEK)");
260 |
261 | for (int i = 0; i < results.size(); i++) {
262 | cvSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
263 | }
264 |
265 | areaChart.getData().add(cvSeries);
266 | }
267 | public void costPerfIndex(){
268 | ArrayList results = planner.calcCPI();
269 | searchButton.setDisable(true);
270 | XYChart.Series cpiSeries = new XYChart.Series();
271 | areaChart.getData().clear();
272 |
273 | calcDescrip.setText("The ratio of Earned Value (EV) over Actual Cost (AC)");
274 | calcResult.setText("Current week: " + weekSelected + ", CPI: " + Math.round(results.get(Integer.valueOf(weekSelected)-1)*100.0000)/100.0000);
275 | calcFormula.setText("(EV / AC)");
276 |
277 | cpiSeries.setName("Cost Performance Index");
278 | xAxis.setLabel("Week");
279 | yAxis.setLabel("Index");
280 |
281 | for (int i = 0; i < results.size(); i++) {
282 | cpiSeries.getData().add(new XYChart.Data(Integer.toString(i+1), results.get(i)));
283 |
284 | }
285 |
286 | areaChart.getData().add(cpiSeries);
287 | }
288 |
289 | public void enableSearch(ActionEvent actionEvent) {
290 | searchButton.setDisable(false);
291 | }
292 | }
293 |
294 |
--------------------------------------------------------------------------------
/src/controllers/ProjectScheduleController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.beans.Observable;
4 | import javafx.beans.property.SimpleStringProperty;
5 | import javafx.collections.FXCollections;
6 | import javafx.collections.ObservableList;
7 | import javafx.event.ActionEvent;
8 | import javafx.fxml.FXML;
9 | import javafx.fxml.FXMLLoader;
10 | import javafx.fxml.Initializable;
11 | import javafx.scene.Node;
12 | import javafx.scene.Parent;
13 | import javafx.scene.Scene;
14 | import javafx.scene.chart.*;
15 | import javafx.scene.control.*;
16 | import javafx.scene.control.cell.PropertyValueFactory;
17 | import javafx.scene.layout.HBox;
18 | import javafx.scene.text.Text;
19 | import javafx.stage.Stage;
20 | import javafx.stage.Window;
21 | import member_manager.Member;
22 | import member_manager.Schedule;
23 |
24 | import java.io.IOException;
25 | import java.net.URL;
26 | import java.time.LocalDate;
27 | import java.time.Month;
28 | import java.util.ArrayList;
29 | import java.util.ResourceBundle;
30 |
31 | public class ProjectScheduleController extends MainController implements Initializable {
32 |
33 | @FXML
34 | private Text headline;
35 | @FXML
36 | private TableView tableView;
37 | @FXML
38 | private TableColumn id;
39 | @FXML
40 | private TableColumn task;
41 | @FXML
42 | private TableColumn startDate;
43 | @FXML
44 | private TableColumn finishDate;
45 | @FXML
46 | private TableColumn duration;
47 | @FXML
48 | private TableColumn resources;
49 |
50 | @FXML
51 | public void backProject(ActionEvent event) throws IOException {
52 |
53 | Parent backProjectMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/projectOverview.fxml"));
54 | Scene backProjectMemberScene = new Scene(backProjectMemberParent);
55 |
56 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
57 |
58 | window.setScene(backProjectMemberScene);
59 | window.show();
60 | }
61 |
62 | @FXML
63 | public void loadAnalysis(ActionEvent event) throws IOException {
64 |
65 | id.setCellValueFactory(new PropertyValueFactory("id"));
66 | task.setCellValueFactory(new PropertyValueFactory("task"));
67 | startDate.setCellValueFactory(new PropertyValueFactory("startDate"));
68 | finishDate.setCellValueFactory(new PropertyValueFactory("finishDate"));
69 | duration.setCellValueFactory(new PropertyValueFactory("duration"));
70 | resources.setCellValueFactory(new PropertyValueFactory("resources"));
71 |
72 | headline.setText("Analysis");
73 |
74 | tableView.setItems(getAnalysis());
75 | }
76 |
77 | @FXML
78 | public void loadUI(ActionEvent event) throws IOException {
79 |
80 | id.setCellValueFactory(new PropertyValueFactory("id"));
81 | task.setCellValueFactory(new PropertyValueFactory("task"));
82 | startDate.setCellValueFactory(new PropertyValueFactory("startDate"));
83 | finishDate.setCellValueFactory(new PropertyValueFactory("finishDate"));
84 | duration.setCellValueFactory(new PropertyValueFactory("duration"));
85 | resources.setCellValueFactory(new PropertyValueFactory("resources"));
86 |
87 | headline.setText("UI Design");
88 |
89 | tableView.setItems(getUIDesign());
90 | }
91 |
92 | @FXML
93 | public void loadDevelopment(ActionEvent event) throws IOException {
94 | id.setCellValueFactory(new PropertyValueFactory("id"));
95 | task.setCellValueFactory(new PropertyValueFactory("task"));
96 | startDate.setCellValueFactory(new PropertyValueFactory("startDate"));
97 | finishDate.setCellValueFactory(new PropertyValueFactory("finishDate"));
98 | duration.setCellValueFactory(new PropertyValueFactory("duration"));
99 | resources.setCellValueFactory(new PropertyValueFactory("resources"));
100 |
101 | headline.setText("Development");
102 |
103 | tableView.setItems(getDevelopment());
104 | }
105 |
106 | @FXML
107 | public void loadCompletion(ActionEvent event) throws IOException {
108 | id.setCellValueFactory(new PropertyValueFactory("id"));
109 | task.setCellValueFactory(new PropertyValueFactory("task"));
110 | startDate.setCellValueFactory(new PropertyValueFactory("startDate"));
111 | finishDate.setCellValueFactory(new PropertyValueFactory("finishDate"));
112 | duration.setCellValueFactory(new PropertyValueFactory("duration"));
113 | resources.setCellValueFactory(new PropertyValueFactory("resources"));
114 |
115 | headline.setText("Completion");
116 |
117 | tableView.setItems(getCompletion());
118 | }
119 |
120 | @Override
121 | public void initialize(URL url, ResourceBundle resourceBundle) {
122 |
123 | id.setCellValueFactory(new PropertyValueFactory("id"));
124 | task.setCellValueFactory(new PropertyValueFactory("task"));
125 | startDate.setCellValueFactory(new PropertyValueFactory("startDate"));
126 | finishDate.setCellValueFactory(new PropertyValueFactory("finishDate"));
127 | duration.setCellValueFactory(new PropertyValueFactory("duration"));
128 | resources.setCellValueFactory(new PropertyValueFactory("resources"));
129 |
130 | headline.setText("Analysis");
131 |
132 | tableView.setItems(getAnalysis());
133 | }
134 |
135 | public ObservableList getAnalysis(){
136 | ObservableList analysis = FXCollections.observableArrayList();
137 |
138 | analysis.add(new Schedule("1", "Analysis", LocalDate.of(2019, Month.NOVEMBER, 04),
139 | LocalDate.of(2019, Month.NOVEMBER, 17), "13 days",
140 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
141 |
142 | analysis.add(new Schedule("2", "Planning Meetings", LocalDate.of(2019, Month.NOVEMBER, 11),
143 | LocalDate.of(2019, Month.NOVEMBER, 14), "4 days",
144 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
145 |
146 | analysis.add(new Schedule("3", "Create Class Diagram", LocalDate.of(2019, Month.NOVEMBER, 13),
147 | LocalDate.of(2019, Month.NOVEMBER, 15), "3 days",
148 | "Christian, Linus I, Clementine, Hjalmar"));
149 |
150 | analysis.add(new Schedule("4", "Analysis Finished", LocalDate.of(2019, Month.NOVEMBER, 17),
151 | LocalDate.of(2019, Month.NOVEMBER, 19), "1 day", ""));
152 |
153 | return analysis;
154 | }
155 |
156 | public ObservableList getUIDesign(){
157 |
158 | ObservableList UIDesign = FXCollections.observableArrayList();
159 |
160 | UIDesign.add(new Schedule("5", "UI Design", LocalDate.of(2019, Month.NOVEMBER, 18),
161 | LocalDate.of(2019, Month.DECEMBER, 22), "35 days",
162 | "Clementine, Hugo, Linus I, Christian"));
163 |
164 | UIDesign.add(new Schedule("6", "Migration to JavaFX", LocalDate.of(2019, Month.NOVEMBER, 18),
165 | LocalDate.of(2019, Month.DECEMBER, 01), "14 days",
166 | "Clementine, Linus I, Christian"));
167 |
168 | UIDesign.add(new Schedule("7", "Create FXML Files", LocalDate.of(2019, Month.NOVEMBER, 22),
169 | LocalDate.of(2019, Month.DECEMBER, 22), "29 days",
170 | "Christian, Linus I, Clementine, Hjalmar"));
171 |
172 | UIDesign.add(new Schedule("8", "Create Controllers", LocalDate.of(2019, Month.NOVEMBER, 22),
173 | LocalDate.of(2019, Month.DECEMBER, 22), "29 day",
174 | "Cleemntine, Linus I, Christian, Hugo"));
175 |
176 | UIDesign.add(new Schedule("9", "UI Design Finished", LocalDate.of(2019, Month.DECEMBER, 22),
177 | LocalDate.of(2019, Month.DECEMBER, 22), "1 day", ""));
178 |
179 | return UIDesign;
180 | }
181 |
182 | public ObservableList getDevelopment(){
183 |
184 | ObservableList development = FXCollections.observableArrayList();
185 |
186 | development.add(new Schedule("10", "Development", LocalDate.of(2019, Month.NOVEMBER, 18),
187 | LocalDate.of(2020, Month.JANUARY, 10), "54 days",
188 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
189 |
190 | development.add(new Schedule("11", "Develop Methods", LocalDate.of(2019, Month.NOVEMBER, 18),
191 | LocalDate.of(2020, Month.JANUARY, 10), "54 days",
192 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
193 |
194 | development.add(new Schedule("12", "Implement Json", LocalDate.of(2019, Month.NOVEMBER, 25),
195 | LocalDate.of(2019, Month.DECEMBER, 07), "13 days",
196 | "Linus Å, Christian, Altug, Hjalmar"));
197 |
198 | development.add(new Schedule("13", "Finish Coding", LocalDate.of(2019, Month.NOVEMBER, 25),
199 | LocalDate.of(2020, Month.JANUARY, 10), "54 days",
200 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
201 |
202 | development.add(new Schedule("14", "Development Finished", LocalDate.of(2020, Month.JANUARY, 10),
203 | LocalDate.of(2020, Month.JANUARY, 10), "1 day", ""));
204 |
205 | return development;
206 | }
207 |
208 | public ObservableList getCompletion(){
209 |
210 | ObservableList completion = FXCollections.observableArrayList();
211 |
212 | completion.add(new Schedule("15", "Completion", LocalDate.of(2019, Month.DECEMBER, 17),
213 | LocalDate.of(2020, Month.JANUARY, 10), "25 days",
214 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
215 |
216 | completion.add(new Schedule("16", "Create Executable", LocalDate.of(2020, Month.JANUARY, 07),
217 | LocalDate.of(2020, Month.JANUARY, 10), "4 days",
218 | "Hugo, Linus Å "));
219 |
220 | completion.add(new Schedule("17", "Final Report", LocalDate.of(2019, Month.DECEMBER, 17),
221 | LocalDate.of(2020, Month.JANUARY, 10), "25 days",
222 | "Clementine, Hugo, Linus I, Linus Å, Christian, Altug, Hjalmar"));
223 |
224 | return completion;
225 | }
226 |
227 | }
228 |
229 |
--------------------------------------------------------------------------------
/src/controllers/dashboardController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.event.ActionEvent;
4 | import javafx.fxml.FXML;
5 | import javafx.fxml.FXMLLoader;
6 | import javafx.scene.Node;
7 | import javafx.scene.Parent;
8 | import javafx.scene.Scene;
9 | import javafx.scene.control.Button;
10 | import javafx.stage.Stage;
11 | import json_reader_writer.JsonReader;
12 | import json_reader_writer.JsonWriter;
13 | import member_manager.Planner;
14 |
15 | import java.io.IOException;
16 |
17 | public class dashboardController extends MainController {
18 |
19 | @FXML
20 | private Button exitApp;
21 | @FXML
22 | private Button saveDataButton;
23 | @FXML
24 | private Button loadDataButton;
25 | @FXML
26 | private Button projectOverviewButton;
27 | @FXML
28 | private Button newMilestoneButton;
29 | @FXML
30 | private Button viewMemberButton;
31 | @FXML
32 | private Button newMemberButton;
33 |
34 | private static boolean loaded = false;
35 |
36 | public void initialize() {
37 | if (!loaded) {
38 | saveDataButton.setDisable(true);
39 | projectOverviewButton.setDisable(true);
40 | newMilestoneButton.setDisable(true);
41 | viewMemberButton.setDisable(true);
42 | newMemberButton.setDisable(true);
43 | } else {
44 | loadButtons();
45 | }
46 | }
47 |
48 | public void loadButtons() {
49 | saveDataButton.setDisable(false);
50 | projectOverviewButton.setDisable(false);
51 | newMilestoneButton.setDisable(false);
52 | viewMemberButton.setDisable(false);
53 | newMemberButton.setDisable(false);
54 | }
55 |
56 | public void addMember(ActionEvent event) throws IOException {
57 |
58 | Parent addMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/newMember.fxml"));
59 | Scene addMemberScene = new Scene(addMemberParent);
60 |
61 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
62 |
63 | window.setScene(addMemberScene);
64 | window.show();
65 | }
66 |
67 | public void viewMember(ActionEvent event) throws IOException {
68 |
69 | Parent viewMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/userInfo.fxml"));
70 | Scene viewMemberScene = new Scene(viewMemberParent);
71 |
72 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
73 |
74 | window.setScene(viewMemberScene);
75 | window.show();
76 | }
77 | @FXML
78 | public void projectOverview(ActionEvent event) throws IOException{
79 |
80 | Parent projectMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/projectOverview.fxml"));
81 | Scene projectMemberScene = new Scene(projectMemberParent);
82 |
83 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
84 |
85 | window.setScene(projectMemberScene);
86 | window.show();
87 |
88 | }
89 |
90 | public void contactUs(ActionEvent event) throws IOException{
91 | Parent contactUsParent = FXMLLoader.load(getClass().getResource("../fxml-files/contactUs.fxml"));
92 | Scene contactUsScene = new Scene(contactUsParent);
93 |
94 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
95 |
96 | window.setScene(contactUsScene);
97 | window.show();
98 | }
99 |
100 |
101 | public void newMilestone(ActionEvent event) throws IOException {
102 |
103 | Parent milestoneMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/milestones.fxml"));
104 | Scene milestoneMemberScene = new Scene(milestoneMemberParent);
105 |
106 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
107 |
108 | window.setScene(milestoneMemberScene);
109 | window.show();
110 | }
111 |
112 | public void loadData(){
113 | JsonReader reader = new JsonReader();
114 | planner = reader.loadPlanner();
115 | loaded = true;
116 | loadButtons();
117 | }
118 | public void saveState(){
119 | JsonWriter writer = new JsonWriter();
120 | writer.savePlanner(planner);
121 | }
122 |
123 | public void exit(){
124 | Stage stage = (Stage) exitApp.getScene().getWindow();
125 | stage.close();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/controllers/editMemberController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 |
4 | import id_generator.GeneratorMain;
5 | import javafx.collections.FXCollections;
6 | import javafx.collections.ObservableList;
7 | import javafx.event.ActionEvent;
8 | import javafx.fxml.FXML;
9 | import javafx.fxml.FXMLLoader;
10 | import javafx.scene.Node;
11 | import javafx.scene.Parent;
12 | import javafx.scene.Scene;
13 | import javafx.scene.control.Alert;
14 | import javafx.scene.control.Button;
15 | import javafx.scene.control.ComboBox;
16 | import javafx.scene.control.TextField;
17 | import javafx.stage.Stage;
18 | import javafx.stage.Window;
19 | import member_manager.Member;
20 |
21 | import java.io.IOException;
22 |
23 | public class editMemberController extends MainController {
24 | @FXML
25 | private ComboBox memberIdDropdown;
26 | @FXML
27 | private TextField searchForID;
28 | @FXML
29 | private Button saveButton;
30 | @FXML
31 | private TextField updateName;
32 | @FXML
33 | private TextField updateLastName;
34 | @FXML
35 | private TextField updateSalary;
36 | @FXML
37 | private TextField updatedFirstName;
38 | @FXML
39 | private TextField updatedLastName;
40 | @FXML
41 | private TextField updatedSalary;
42 | @FXML
43 | private TextField showID;
44 |
45 | //Checks for valid ID and updates member information.
46 | public void saveInfo(ActionEvent actionEvent) {
47 | int searchedID = 0;
48 | boolean IDValid = true;
49 | Window owner = saveButton.getScene().getWindow();
50 |
51 | if (searchForID.getText().isEmpty()) {
52 | AlertHelper.showAlert(Alert.AlertType.INFORMATION, owner, "Info", "Search field must be filled in!");
53 | System.out.println("Search failed (Empty search).");
54 | IDValid = false;
55 | } else if (!GeneratorMain.isParsable(searchForID.getText())) {
56 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "ID's must be 5-digit integers!");
57 | System.out.println("Search failed (Invalid ID format, non-number characters).");
58 | IDValid = false;
59 | } else if (Integer.parseInt(searchForID.getText()) > 99999) {
60 | AlertHelper.showAlert(Alert.AlertType.WARNING, owner, "Error", "ID's are positive 5-digit integers!");
61 | System.out.println("Search failed (Invalid ID format, more than 5 digits");
62 | IDValid = false;
63 | } else if (Integer.parseInt(searchForID.getText()) < 10000) {
64 | AlertHelper.showAlert(Alert.AlertType.WARNING, owner, "Error", "ID's are positive 5-digit integers!");
65 | System.out.println("Search failed (Invalid ID format, less than 5 digits OR negative input).");
66 | IDValid = false;
67 |
68 | } else if (GeneratorMain.isParsable(searchForID.getText())) {
69 | searchedID = Integer.parseInt(searchForID.getText());
70 |
71 | for (Member member : planner.members) {
72 | if (searchedID == member.getId()) {
73 | if (IDValid) {
74 | if (updateName.getText().isEmpty()) {
75 | //keeps same firstname if no new name is entered
76 | } else {
77 | member.setFirstName(updateName.getText());
78 | }
79 | if (updateLastName.getText().isEmpty()) {
80 | //keeps same lastname if no new lastname is entered
81 | } else {
82 | member.setLastName(updateLastName.getText());
83 | }
84 | if (updateSalary.getText().isEmpty()) {
85 | //keeps same salary if no new salary is entered
86 | } else {
87 | double updatedSalary = Double.parseDouble(updateSalary.getText());
88 | member.setSalary(updatedSalary);
89 | }
90 | //Sets updated information to "Updated member information" textfields and clears input-textfields.
91 | showID.setText(Integer.toString(member.getId()));
92 | updatedFirstName.setText(member.getFirstName());
93 | updatedLastName.setText(member.getLastName());
94 | updatedSalary.setText(String.valueOf(member.getSalary()));
95 | updateName.clear();
96 | updateLastName.clear();
97 | updateSalary.clear();
98 |
99 | }
100 | }
101 | }
102 | }
103 | }
104 |
105 | public void initialize (){
106 | ObservableList memberDropdownItems = FXCollections.observableArrayList();
107 | for (Member member : planner.members) {
108 | memberDropdownItems.add(Integer.toString(member.getId()) + " : " + member.getFirstName() + " " + member.getLastName());
109 | }
110 | memberIdDropdown.setItems(memberDropdownItems);
111 | }
112 |
113 | public void setText (ActionEvent actionEvent){
114 | searchForID.setText(memberIdDropdown.getValue().toString().substring(0, 5));
115 | }
116 |
117 |
118 | @Override
119 | public void back (ActionEvent event) throws IOException {
120 |
121 | Parent backMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/userInfo.fxml"));
122 | Scene backMemberScene = new Scene(backMemberParent);
123 |
124 | Stage window = (Stage) ((Node) event.getSource()).getScene().getWindow();
125 |
126 | window.setScene(backMemberScene);
127 | window.show();
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/src/controllers/milestonesController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.event.ActionEvent;
4 | import javafx.fxml.FXML;
5 | import javafx.scene.control.DatePicker;
6 | import javafx.scene.control.TextField;
7 | import member_manager.Member;
8 | import member_manager.Milestone;
9 |
10 | import java.util.ArrayList;
11 |
12 | public class milestonesController extends MainController {
13 |
14 | @FXML
15 | private TextField milestoneNameRegister;
16 | @FXML
17 | private TextField milestoneDescripRegister;
18 | @FXML
19 | private TextField milestoneMemberRegister;
20 | @FXML
21 | private DatePicker startDateRegister;
22 | @FXML
23 | private DatePicker endDateRegister;
24 |
25 |
26 | @FXML
27 | public void registerMilestone(ActionEvent event) {
28 | milestoneMemberRegister.getText();
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/controllers/newMemberController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import id_generator.GeneratorMain;
4 | import javafx.event.ActionEvent;
5 | import javafx.fxml.FXML;
6 | import javafx.scene.control.Alert;
7 | import javafx.scene.control.Button;
8 | import javafx.scene.control.TextField;
9 | import javafx.stage.Window;
10 | import json_reader_writer.JsonReader;
11 | import json_reader_writer.JsonWriter;
12 | import member_manager.Member;
13 | import member_manager.Planner;
14 |
15 | public class newMemberController extends MainController {
16 |
17 | @FXML
18 | private TextField firstNameRegister;
19 | @FXML
20 | private TextField lastNameRegister;
21 | @FXML
22 | private TextField dobRegister;
23 | @FXML
24 | private TextField salaryRegister;
25 | @FXML
26 | private Button registerButton;
27 |
28 |
29 |
30 | public void registerMember(ActionEvent event) throws NumberFormatException {
31 | Window owner = registerButton.getScene().getWindow(); //setup the popup
32 | boolean success = true;
33 |
34 | if (firstNameRegister.getText().isEmpty()) { //checks if first name field is empty
35 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "First name field can not be empty!");
36 | System.out.println("First name field failed.");
37 | success = false;
38 |
39 | } if (lastNameRegister.getText().isEmpty()) { //checks if last name field is empty
40 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Last name field can not be empty!");
41 | System.out.println("Last name field failed.");
42 | success = false;
43 | } if (GeneratorMain.isParsable(dobRegister.getText())) { //checks if birthday field valid but < 0 or > 991231
44 | int tempInt = Integer.parseInt(dobRegister.getText());
45 | if (tempInt <= 0) {
46 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Age can not be less than 0!");
47 | System.out.println("Birthday field failed (negative input).");
48 | success = false;
49 | } else if (tempInt > 20181212) { //The highest accepted value as of the day implemented.
50 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Please follow the appropriate format YYMMDD!");
51 | System.out.println("Birthday field failed (input exceeds max accepted input).");
52 | success = false;
53 | }
54 | } if (!GeneratorMain.isParsable(dobRegister.getText())) { //checks if birthday field is empty or invalid
55 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Please follow the appropriate format YYMMDD!");
56 | System.out.println("Birthday field failed (invalid input).");
57 | success = false;
58 | } if (GeneratorMain.isParsable(salaryRegister.getText())) {
59 | double tempSalary = Double.parseDouble(salaryRegister.getText());
60 | if (tempSalary < 80) {
61 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Salary must be at least minimum wage! (Currently 80SEK)");
62 | System.out.println("Salary field failed (invalid salary amount).");
63 | success = false;
64 | }
65 | } if (!GeneratorMain.isParsable(salaryRegister.getText()) || salaryRegister.getText().isEmpty()) {
66 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "Salary must be a number greater than minimum wage (80SEK).");
67 | System.out.println("Salary field failed (invalid salary input).");
68 | success = false;
69 | } else {
70 | int genID = GeneratorMain.generateID(firstNameRegister.getText(), lastNameRegister.getText(), Integer.parseInt(dobRegister.getText()));
71 | System.out.println("ABOVE TEXT IS JUST CONSOLE DEBUGGING FOR ID GEN. IF NO TEXT FOLLOWS THEN NO MEMBER WAS CREATED.");
72 | for (Member member : MainController.planner.members) {
73 | if (genID == member.getId()) {
74 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "User with ID: " + genID + " already exists. Please proceed to the contact page if you believe this is an error.");
75 | success = false;
76 | }
77 | }
78 | }
79 |
80 | if (success) {
81 | AlertHelper.showAlert(Alert.AlertType.CONFIRMATION, owner, "Success", "Member successfully registered! \n" + firstNameRegister.getText() + "'s generated ID is: " + GeneratorMain.generateID(firstNameRegister.getText(), lastNameRegister.getText(), Integer.parseInt(dobRegister.getText())));
82 | System.out.println("Member registration successful.");
83 | //Add the member to the Planner
84 | planner.addMember(firstNameRegister.getText(), lastNameRegister.getText(), Integer.parseInt(dobRegister.getText()), Double.parseDouble(salaryRegister.getText()));
85 | System.out.println(firstNameRegister.getText() + " was added to the planner.");
86 | System.out.println(planner.members);
87 |
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/controllers/riskMatrixController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import javafx.event.ActionEvent;
4 | import javafx.event.Event;
5 | import javafx.fxml.FXML;
6 | import javafx.fxml.FXMLLoader;
7 | import javafx.scene.Node;
8 | import javafx.scene.Parent;
9 | import javafx.scene.Scene;
10 | import javafx.scene.layout.AnchorPane;
11 | import javafx.stage.Stage;
12 | import json_reader_writer.JsonReader;
13 | import member_manager.RiskMatrix;
14 |
15 | import java.awt.*;
16 | import java.io.IOException;
17 | import java.util.ArrayList;
18 |
19 | public class riskMatrixController extends MainController {
20 |
21 | @FXML
22 | private javafx.scene.control.Label e11;
23 | @FXML
24 | private javafx.scene.control.Label e12;
25 | @FXML
26 | private javafx.scene.control.Label e13;
27 | @FXML
28 | private javafx.scene.control.Label e14;
29 | @FXML
30 | private javafx.scene.control.Label e15;
31 | @FXML
32 | private javafx.scene.control.Label l22;
33 | @FXML
34 | private javafx.scene.control.Label l23;
35 | @FXML
36 | private javafx.scene.control.Label l21;
37 | @FXML
38 | private javafx.scene.control.Label l24;
39 | @FXML
40 | private javafx.scene.control.Label l25;
41 | @FXML
42 | private javafx.scene.control.Label l32;
43 | @FXML
44 | private javafx.scene.control.Label l34;
45 | @FXML
46 | private javafx.scene.control.Label l44;
47 | @FXML
48 | private javafx.scene.control.Label l33;
49 | @FXML
50 | private javafx.scene.control.Label l45;
51 | @FXML
52 | private javafx.scene.control.Label l31;
53 | @FXML
54 | private javafx.scene.control.Label l42;
55 | @FXML
56 | private javafx.scene.control.Label l43;
57 | @FXML
58 | private javafx.scene.control.Label l41;
59 |
60 | @FXML
61 | public void visualRisks() {
62 | JsonReader jsonReader = new JsonReader();
63 | ArrayList risks;
64 | risks = jsonReader.loadRiskMatrix();
65 | e11.setText(risks.get(0).getRiskName());
66 | l21.setText(risks.get(0).getVeryLikely());
67 | l31.setText(risks.get(0).getPossible());
68 | l41.setText(risks.get(0).getUnlikely());
69 |
70 | e12.setText(risks.get(1).getRiskName());
71 | l22.setText(risks.get(1).getVeryLikely());
72 | l32.setText(risks.get(1).getPossible());
73 | l42.setText(risks.get(1).getUnlikely());
74 |
75 | e13.setText(risks.get(2).getRiskName());
76 | l23.setText(risks.get(2).getVeryLikely());
77 | l33.setText(risks.get(2).getPossible());
78 | l43.setText(risks.get(2).getUnlikely());
79 |
80 | e14.setText(risks.get(3).getRiskName());
81 | l24.setText(risks.get(3).getVeryLikely());
82 | l34.setText(risks.get(3).getPossible());
83 | l44.setText(risks.get(3).getUnlikely());
84 |
85 | e15.setText(risks.get(4).getRiskName());
86 | l25.setText(risks.get(4).getVeryLikely());
87 | l45.setText(risks.get(4).getUnlikely());
88 | l34.setText(risks.get(4).getPossible());
89 |
90 |
91 |
92 |
93 | }
94 |
95 | public void initialize () {
96 | visualRisks();
97 | }
98 |
99 | @Override
100 | public void back(ActionEvent event) throws IOException {
101 |
102 | Parent backMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/projectOverview.fxml"));
103 | Scene backMemberScene = new Scene(backMemberParent);
104 |
105 |
106 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
107 |
108 | window.setScene(backMemberScene);
109 | window.show();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/controllers/userInfoController.java:
--------------------------------------------------------------------------------
1 | package controllers;
2 |
3 | import id_generator.GeneratorMain;
4 | import javafx.collections.FXCollections;
5 | import javafx.collections.ObservableList;
6 | import javafx.event.ActionEvent;
7 | import javafx.fxml.FXML;
8 | import javafx.fxml.FXMLLoader;
9 | import javafx.scene.Node;
10 | import javafx.scene.Parent;
11 | import javafx.scene.Scene;
12 | import javafx.scene.chart.*;
13 | import javafx.scene.control.*;
14 | import javafx.scene.text.Text;
15 | import javafx.stage.Stage;
16 | import javafx.stage.Window;
17 | import javafx.util.Duration;
18 | import member_manager.Member;
19 |
20 | import java.io.IOException;
21 | import java.util.ArrayList;
22 |
23 | public class userInfoController extends MainController {
24 | @FXML
25 | private NumberAxis yAxis;
26 | @FXML
27 | private CategoryAxis xAxis;
28 | @FXML
29 | private BarChart barChart;
30 | @FXML
31 | private TextField searchForID;
32 | @FXML
33 | private Button searchForIDButton;
34 | @FXML
35 | private Button showHours;
36 | @FXML
37 | private Button showSalary;
38 | @FXML
39 | private Button submitButton;
40 | @FXML
41 | private Text revealName;
42 | @FXML
43 | private Text revealID;
44 | @FXML
45 | private Text userInfoDescription;
46 | @FXML
47 | private PieChart pieChart;
48 | @FXML
49 | private ComboBox compareUserDropdown;
50 | @FXML
51 | private ComboBox compareHoursSalaryDropdown;
52 | @FXML
53 | private ComboBox memberIdDropdown;
54 |
55 | public void initialize() {
56 | ObservableList memberDropdownItems = FXCollections.observableArrayList();
57 | for (Member member : planner.members) {
58 | memberDropdownItems.add(Integer.toString(member.getId()) + " : " + member.getFirstName() + " " + member.getLastName());
59 | }
60 | memberIdDropdown.setItems(memberDropdownItems);
61 | }
62 |
63 | public void setText(ActionEvent actionEvent) {
64 | searchForID.setText(memberIdDropdown.getValue().toString().substring(0, 5));
65 | search();
66 | }
67 |
68 | public void search() {
69 |
70 | Window owner = searchForIDButton.getScene().getWindow();
71 | int searchedID = 0;
72 | boolean IDValid = true;
73 | boolean IDFound = false;
74 |
75 | if (searchForID.getText().isEmpty()) {
76 | AlertHelper.showAlert(Alert.AlertType.INFORMATION, owner, "Info", "Search field must be filled in!");
77 | System.out.println("Search failed (Empty search).");
78 | IDValid = false;
79 | } else if (GeneratorMain.isParsable(searchForID.getText())) {
80 | searchedID = Integer.parseInt(searchForID.getText());
81 |
82 | ObservableList optionsIds = FXCollections.observableArrayList();
83 | for (Member member : planner.members) {
84 | if (member.getId() != Integer.parseInt(searchForID.getText())) {
85 | optionsIds.add((member.getId()) + " : " + member.getFirstName() + " " + member.getLastName().substring(0, 1) + ".");
86 | }
87 | }
88 | compareUserDropdown.setItems(optionsIds);
89 |
90 | ObservableList optionsHoursSalary = FXCollections.observableArrayList();
91 | optionsHoursSalary.add("Hours");
92 | optionsHoursSalary.add("Salaries");
93 | compareHoursSalaryDropdown.setItems(optionsHoursSalary);
94 |
95 | if (Integer.parseInt(searchForID.getText()) < 10000) {
96 | AlertHelper.showAlert(Alert.AlertType.WARNING, owner, "Error", "ID's are positive 5-digit integers!");
97 | System.out.println("Search failed (Invalid ID format, less than 5 digits OR negative input).");
98 | IDValid = false;
99 | } else if (Integer.parseInt(searchForID.getText()) > 99999) {
100 | AlertHelper.showAlert(Alert.AlertType.WARNING, owner, "Error", "ID's are positive 5-digit integers!");
101 | System.out.println("Search failed (Invalid ID format, more than 5 digits");
102 | IDValid = false;
103 | }
104 | } else {
105 | if (!GeneratorMain.isParsable(searchForID.getText())) {
106 | AlertHelper.showAlert(Alert.AlertType.ERROR, owner, "Error", "ID's must be 5-digit integers!");
107 | System.out.println("Search failed (Invalid ID format, non-number characters).");
108 | IDValid = false;
109 | }
110 | }
111 | if (IDValid) {
112 | //Input the team member's information into the page
113 | System.out.println(">> Debugger");
114 | System.out.println(planner.members);
115 |
116 | String memberName = "";
117 | for (Member member : planner.members) {
118 | System.out.println(member.getId());
119 | if (searchedID == member.getId()) {
120 | IDFound = true;
121 | memberName = member.getFirstName().concat(" ").concat(member.getLastName());
122 | }
123 | }
124 |
125 | if (IDFound) {
126 | revealName.setText(memberName);
127 | revealID.setText(Integer.toString(searchedID));
128 | System.out.println("Name set to: " + memberName);
129 | System.out.println("ID set to: " + searchedID);
130 |
131 | showHours.setDisable(false);
132 | showSalary.setDisable(false);
133 | submitButton.setDisable(false);
134 | searchForIDButton.setDisable(false);
135 | compareHoursSalaryDropdown.setDisable(false);
136 | compareUserDropdown.setDisable(false);
137 |
138 | userInfoDescription.setText("Milestones worked on by " + memberName + ":\n" +
139 | planner.getMilestonesWorkedOn(searchedID).toString().substring(1, planner.getMilestonesWorkedOn(searchedID).toString().length() -1));
140 | } else {
141 | AlertHelper.showAlert(Alert.AlertType.INFORMATION, owner, "Error", "Member ID does not yet exist.");
142 | }
143 | }
144 | }
145 |
146 | public void editMember(ActionEvent event) throws IOException{
147 |
148 | Parent editMemberParent = FXMLLoader.load(getClass().getResource("../fxml-files/editMember.fxml"));
149 | Scene editMemberScene = new Scene(editMemberParent);
150 |
151 | Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
152 |
153 | window.setScene(editMemberScene);
154 | window.show();
155 |
156 | }
157 |
158 | public String getName() {
159 | int ID = 0;
160 | if (GeneratorMain.isParsable(searchForID.getText())) {
161 | ID = Integer.parseInt(searchForID.getText());
162 | }
163 | String name = "";
164 |
165 | for (Member member : planner.members) {
166 | if (ID == member.getId()) {
167 | name = member.getFirstName() + " " + member.getLastName();
168 | }
169 | }
170 | return name;
171 | }
172 |
173 | public void showHours(ActionEvent event) throws IOException {
174 | //draw pie chart
175 | pieChart.getData().clear();
176 |
177 | ObservableList chartData = FXCollections.observableArrayList();
178 |
179 | for (Member member : planner.members) {
180 | int hours = (int) planner.getAllHoursForMember(member.getId());
181 | String memberID = member.getFirstName() + ": " + hours + " hours";
182 | chartData.add(new PieChart.Data(memberID, hours));
183 | }
184 |
185 | pieChart.setLabelsVisible(false);
186 | pieChart.setLegendVisible(false);
187 | pieChart.setTitle("Hours worked");
188 | pieChart.setData(chartData);
189 |
190 | pieChart.getData().stream().forEach(data -> {
191 | Tooltip valuesToolTip = new Tooltip();
192 | valuesToolTip.setText(data.getName());
193 | Tooltip.install(data.getNode(), valuesToolTip);
194 | valuesToolTip.setShowDelay(Duration.ZERO);
195 | });
196 |
197 | //draw graph
198 | String name = getName();
199 | barChart.setTitle("Hours worked by: " + name);
200 | xAxis.setLabel("Week");
201 | yAxis.setLabel("Hours");
202 |
203 | barChart.getData().clear();
204 | barChart.autosize();
205 |
206 | XYChart.Series dataSeries = new XYChart.Series();
207 | dataSeries.setName("Hours Worked");
208 |
209 | double totalHours = 0;
210 |
211 | for (Member member : planner.members) {
212 | totalHours = totalHours + planner.getAllHoursForMember(member.getId());
213 | }
214 |
215 | double avgHours = Math.round(totalHours / planner.members.size());
216 |
217 | for (Integer week : planner.timesheet.keySet()) {
218 | double hoursWorked = 0;
219 | hoursWorked = planner.getWeeklyHoursForMember(week, Integer.parseInt(searchForID.getText()));
220 | dataSeries.getData().add(new XYChart.Data<>(Integer.toString(week), hoursWorked));
221 | }
222 |
223 | xAxis.setAnimated(false);
224 | yAxis.setAnimated(false);
225 | barChart.getData().add(dataSeries);
226 |
227 | //add in info
228 | userInfoDescription.setText(name + "'s total hours are " + planner.getAllHoursForMember(Integer.parseInt(searchForID.getText())) + " hours. Compared to the total group average of " + avgHours + ".");
229 | }
230 |
231 | public void showSalary(ActionEvent event) throws IOException {
232 |
233 | //do pieChart
234 | pieChart.getData().clear();
235 |
236 | ObservableList chartData = FXCollections.observableArrayList();
237 |
238 | double totalSalary = 0;
239 | for (Member member : planner.members) {
240 | totalSalary = member.getSalary() * planner.getAllHoursForMember(member.getId());
241 | String memberID = member.getFirstName() + ": " + totalSalary + " SEK";
242 | chartData.add(new PieChart.Data(memberID, totalSalary));
243 | }
244 |
245 | pieChart.setLabelsVisible(false);
246 | pieChart.setLegendVisible(true);
247 | pieChart.setTitle("Salary Earned");
248 | pieChart.setData(chartData);
249 |
250 | pieChart.getData().stream().forEach(data -> {
251 | Tooltip valuesToolTip = new Tooltip();
252 | valuesToolTip.setText(data.getName());
253 | Tooltip.install(data.getNode(), valuesToolTip);
254 | valuesToolTip.setShowDelay(Duration.ZERO);
255 | });
256 |
257 | //Do barChart
258 | String name = getName();
259 | barChart.setTitle("Salaries earned by: " + name);
260 | xAxis.setLabel("Week");
261 | yAxis.setLabel("Amount (SEK)");
262 |
263 | barChart.getData().clear();
264 | barChart.autosize();
265 |
266 | XYChart.Series dataSeries = new XYChart.Series();
267 | dataSeries.setName("Salary Earned");
268 |
269 | double total = 0;
270 | for (Integer week : planner.timesheet.keySet()) {
271 | total = planner.getWeeklySalaryForMember(week, Integer.parseInt(searchForID.getText()));
272 | dataSeries.getData().add(new XYChart.Data<>(Integer.toString(week), total));
273 | }
274 |
275 | xAxis.setAnimated(false);
276 | yAxis.setAnimated(false);
277 | barChart.getData().add(dataSeries);
278 |
279 | double avgSalary = 0;
280 | for (Member member : planner.members) {
281 | avgSalary = Math.round((avgSalary + (planner.getTotalSalaryForMember(member.getId()))) / planner.members.size());
282 | }
283 |
284 | //add in info
285 | userInfoDescription.setText(name + "'s total salary is " + planner.getTotalSalaryForMember(Integer.parseInt(searchForID.getText())) + "sek. Compared to the total group average of " + avgSalary + ".");
286 | }
287 |
288 | public void compareUsers(ActionEvent actionEvent) {
289 | int firstID = Integer.parseInt(searchForID.getText());
290 | String secondID = (String) compareUserDropdown.getValue();
291 | int compareID = Integer.parseInt(secondID.substring(0, 5));
292 | String compareType = (String) compareHoursSalaryDropdown.getValue();
293 |
294 | System.out.println(firstID + ", " + secondID); //debuggers
295 | System.out.println(firstID + ", " + compareID);
296 |
297 | Member member1 = null;
298 | Member member2 = null;
299 |
300 | for (Member member : planner.members) {
301 | if (member.getId() == firstID) {
302 | member1 = member;
303 | } else if (member.getId() == compareID) {
304 | member2 = member;
305 | }
306 | }
307 |
308 | System.out.println(member1);
309 | System.out.println(member2);
310 |
311 | //draw piechart for both members.
312 | pieChart.getData().clear();
313 | pieChart.autosize();
314 |
315 | //lists for hours pie chart
316 | ObservableList hoursMembers = FXCollections.observableArrayList();
317 |
318 | hoursMembers.add(new PieChart.Data(member1.getFirstName(), planner.getAllHoursForMember(member1.getId())));
319 | hoursMembers.add(new PieChart.Data(member2.getFirstName(), planner.getAllHoursForMember(member2.getId())));
320 |
321 | //lists for salaries pie chart
322 | ObservableList salaryMembers = FXCollections.observableArrayList();
323 |
324 | salaryMembers.add(new PieChart.Data(member1.getFirstName(), planner.getTotalSalaryForMember(member1.getId())));
325 | salaryMembers.add(new PieChart.Data(member2.getFirstName(), planner.getTotalSalaryForMember(member2.getId())));
326 |
327 | //data series for hours bar chart
328 | XYChart.Series hoursSeriesMember1 = new XYChart.Series();
329 | hoursSeriesMember1.setName(member1.getFirstName());
330 | XYChart.Series hoursSeriesMember2 = new XYChart.Series();
331 | hoursSeriesMember2.setName(member2.getFirstName());
332 | XYChart.Series salarySeriesMember1 = new XYChart.Series();
333 | salarySeriesMember1.setName(member1.getFirstName());
334 | XYChart.Series salarySeriesMember2 = new XYChart.Series();
335 | salarySeriesMember2.setName(member2.getFirstName());
336 |
337 | for (Integer week : planner.timesheet.keySet()) {
338 | hoursSeriesMember1.getData().add(new XYChart.Data<>(Integer.toString(week), planner.getWeeklyHoursForMember(week, member1.getId())));
339 | salarySeriesMember1.getData().add(new XYChart.Data<>(Integer.toString(week), planner.getWeeklySalaryForMember(week, member1.getId())));
340 | hoursSeriesMember2.getData().add(new XYChart.Data<>(Integer.toString(week), planner.getWeeklyHoursForMember(week, member2.getId())));
341 | salarySeriesMember2.getData().add(new XYChart.Data<>(Integer.toString(week), planner.getWeeklySalaryForMember(week, member2.getId())));
342 | }
343 |
344 | //draw graphs
345 | if (!compareType.isEmpty()) {
346 | if (compareType.equalsIgnoreCase("hours")) {
347 | pieChart.getData().clear();
348 | pieChart.setLegendVisible(true);
349 | pieChart.setLabelsVisible(false);
350 | pieChart.setTitle("Compared Hours");
351 | pieChart.setData(hoursMembers);
352 |
353 | pieChart.getData().stream().forEach(data -> {
354 | Tooltip valuesToolTip = new Tooltip();
355 | valuesToolTip.setText(data.getName() + "\n" + data.getPieValue() + " hours");
356 | Tooltip.install(data.getNode(), valuesToolTip);
357 | valuesToolTip.setShowDelay(Duration.ZERO);
358 | });
359 |
360 | barChart.getData().clear();
361 | barChart.autosize();
362 | xAxis.setAnimated(false);
363 | yAxis.setAnimated(false);
364 | barChart.setTitle("Compared Hours");
365 | barChart.getData().addAll(hoursSeriesMember1, hoursSeriesMember2);
366 |
367 | userInfoDescription.setText(member1.getFirstName() + "'s total hours worked are " + planner.getAllHoursForMember(member1.getId()) +
368 | "\nWhile " + member2.getFirstName() + "'s total hours worked are " + planner.getAllHoursForMember(member2.getId()) + ".");
369 | }
370 | if (compareType.equalsIgnoreCase("salaries")) {
371 | pieChart.getData().clear();
372 | pieChart.setLegendVisible(true);
373 | pieChart.setLabelsVisible(false);
374 | pieChart.setTitle("Compared Salaries");
375 | pieChart.setData(salaryMembers);
376 |
377 | pieChart.getData().stream().forEach(data -> {
378 | Tooltip valuesToolTip = new Tooltip();
379 | valuesToolTip.setText(data.getName() + "\n" + data.getPieValue() + "SEK");
380 | Tooltip.install(data.getNode(), valuesToolTip);
381 | valuesToolTip.setShowDelay(Duration.ZERO);
382 | });
383 |
384 | barChart.getData().clear();
385 | barChart.autosize();
386 | xAxis.setAnimated(false);
387 | yAxis.setAnimated(false);
388 | barChart.setTitle("Compared Salaries");
389 | barChart.getData().addAll(salarySeriesMember1, salarySeriesMember2);
390 |
391 | userInfoDescription.setText(member1.getFirstName() + "'s total earned salary is " + planner.getTotalSalaryForMember(member1.getId()) + "SEK" +
392 | "\nWhereas " + member2.getFirstName() + "'s total earned salary is " + planner.getTotalSalaryForMember(member2.getId()) + "SEK.");
393 | }
394 | }
395 | }
396 | }
397 |
--------------------------------------------------------------------------------
/src/fxml-files/contactUs.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/fxml-files/dashboard.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/fxml-files/editMember.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/fxml-files/milestones.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/fxml-files/newMember.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/fxml-files/projectOverview.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/src/fxml-files/projectSchedule.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/fxml-files/riskMatrix.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/src/fxml-files/userInfo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/src/id_generator/GeneratorMain.java:
--------------------------------------------------------------------------------
1 | package id_generator;
2 |
3 | public class GeneratorMain {
4 |
5 | private static final int SHORTEN_ID = 10;
6 |
7 | //method to create the member's unique ID given their information
8 | public static int generateID(String firstName, String lastName, int birthday) {
9 | int generatedID = 0;
10 | int firstNameSum = 0;
11 | int lastNameSum = 0;
12 | int charsInName = firstName.length() + lastName.length();
13 | char letter;
14 |
15 | //converts first and last names to ASCII values
16 | System.out.println("\n>> Analyzing first name...");
17 | for (int i = 0; i < firstName.length(); i++) {
18 | letter = firstName.charAt(i);
19 | System.out.print("[" + letter + "] --> ");
20 | System.out.println("[" + (int) letter + "]");
21 | firstNameSum = firstNameSum + (int) letter;
22 | }
23 |
24 | System.out.println("\n>> Analyzing last name...");
25 | for (int i = 0; i < lastName.length(); i++) {
26 | letter = lastName.charAt(i);
27 | System.out.print("[" + letter + "] --> ");
28 | System.out.println("[" + (int) letter + "]");
29 | lastNameSum = lastNameSum + (int) letter;
30 | }
31 |
32 | //come debug code to double check math, TODO: COMMENT OUT BEFORE IMPLEMENTATION
33 | System.out.println("\n>> First name ID: " + firstNameSum);
34 | System.out.println(">> Last name ID: " + lastNameSum);
35 |
36 | String concatIDString = (Integer.toString(firstNameSum) + Integer.toString(lastNameSum));
37 | int concatID = Integer.parseInt(concatIDString);
38 | System.out.println(">> Concatenated ID: " + concatID);
39 |
40 | //doMath();
41 | generatedID = ((int) (concatID / Math.sqrt(charsInName)+(Math.sqrt(birthday)))) / SHORTEN_ID ;
42 | System.out.println(">> Generated ID: " + generatedID);
43 |
44 | return generatedID;
45 | }
46 |
47 | //inspiration from https://stackoverflow.com/questions/6456219/java-checking-if-parseint-throws-exception
48 | public static boolean isParsable(String inputText) {
49 | try {
50 | Integer.parseInt(inputText);
51 | return true;
52 | } catch (NumberFormatException e) {
53 | e.printStackTrace();
54 | return false;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/json_reader_writer/JsonReader.java:
--------------------------------------------------------------------------------
1 | package json_reader_writer;
2 |
3 | import java.io.FileReader;
4 | import java.io.IOException;
5 | import java.time.LocalDate;
6 | import java.util.*;
7 |
8 | import member_manager.*;
9 | import org.json.simple.JSONArray;
10 | import org.json.simple.JSONObject;
11 | import org.json.simple.parser.JSONParser;
12 | import org.json.simple.parser.ParseException;
13 |
14 | public class JsonReader {
15 |
16 | public Planner loadPlanner() {
17 | JSONParser jsonParser = new JSONParser();
18 | Planner planner = null;
19 | try {
20 | //Parsing the contents of the JSON file
21 | Object obj = jsonParser.parse(new FileReader("input.json"));
22 | JSONObject jsonObject = (JSONObject) obj;
23 |
24 | //extracting the planner details from Json and creating object.
25 | String projectName = (String) jsonObject.get("projectName");
26 | LocalDate startDate = LocalDate.parse((String) jsonObject.get("startDate"));
27 | LocalDate endDate = LocalDate.parse((String) jsonObject.get("endDate"));
28 | double budget = Double.parseDouble((String)jsonObject.get("budget"));
29 | planner = new Planner(projectName, startDate, endDate, budget);
30 |
31 | } catch (ParseException | IOException e) {
32 | e.printStackTrace();
33 | }
34 | return planner;
35 | }
36 |
37 | //Reader and object creator for the members
38 | public ArrayList loadMember(){
39 | JSONParser jsonParser = new JSONParser();
40 | ArrayList members = new ArrayList<>();
41 |
42 | try {
43 | Object obj = jsonParser.parse(new FileReader("input.json"));
44 | JSONObject jsonObject = (JSONObject) obj;
45 |
46 | JSONArray memberArray = (JSONArray) jsonObject.get("members");
47 |
48 | for (JSONObject object : (Iterable) memberArray) {
49 | String firstName = (String) object.get("firstName");
50 | String lastName = (String) object.get("lastName");
51 | float ID = Integer.parseInt((String) object.get("ID"));
52 | double salary = Double.parseDouble((String) object.get("salary"));
53 | Member member = new Member(firstName, lastName, ID, salary);
54 | members.add(member);
55 | System.out.println(member.getId() + ": " + member.getFirstName());
56 | }
57 | } catch (IOException | ParseException e) {
58 | e.printStackTrace();
59 | }
60 | return members;
61 | }
62 |
63 |
64 | public ArrayList loadMilestone(){
65 |
66 | JSONParser jsonParser = new JSONParser();
67 | ArrayList milestones = new ArrayList<>();
68 |
69 | try {
70 | Object obj = jsonParser.parse(new FileReader("input.json"));
71 | JSONObject jsonObject = (JSONObject) obj;
72 |
73 | JSONArray milestoneArray = (JSONArray) jsonObject.get("milestones");
74 |
75 | for (JSONObject object : (Iterable) milestoneArray) {
76 | String milestoneName = (String) object.get("milestoneName");
77 | String milestoneDescription = (String) object.get("milestoneDescription");
78 | LocalDate startDate = LocalDate.parse((String) object.get("startDate"));
79 | LocalDate plannedEndDate = LocalDate.parse((String) object.get("plannedEndDate"));
80 | LocalDate actualEndDate = LocalDate.parse((String) object.get("actualEndDate"));
81 | JSONObject hoursPerMember = (JSONObject) object.get("hoursPerMember");
82 |
83 |
84 | Milestone milestone = new Milestone(milestoneName, milestoneDescription, startDate, plannedEndDate, actualEndDate, createMembers(hoursPerMember));
85 | milestones.add(milestone);
86 | }
87 | } catch (ParseException | IOException e) {
88 | e.printStackTrace();
89 | }
90 | return milestones;
91 | }
92 |
93 | public Map> loadTimesheet() {
94 | JSONParser jsonParser = new JSONParser();
95 | Map> timesheets = new HashMap<>();
96 |
97 | try {
98 | Object obj = jsonParser.parse(new FileReader("input.json"));
99 | JSONObject jsonObject = (JSONObject) obj;
100 | JSONArray timesheetArray = (JSONArray) jsonObject.get("timesheet");
101 |
102 | for (JSONObject object : (Iterable) timesheetArray) {
103 | int weekNumber = Integer.valueOf((String) object.get("week"));
104 | JSONObject getHoursWorked = (JSONObject) object.get("hoursWorked");
105 | Map membersWithHours = createMembers(getHoursWorked);
106 | timesheets.put(weekNumber, membersWithHours);
107 | }
108 | } catch (ParseException | IOException | InputMismatchException e) {
109 | e.printStackTrace();
110 | }
111 | //System.out.println(timesheets); //debugger
112 | return timesheets;
113 | }
114 |
115 | public ArrayList percentComplete() {
116 | JSONParser jsonParser = new JSONParser();
117 | ArrayList percentages = new ArrayList<>();
118 |
119 | try {
120 | Object obj = jsonParser.parse(new FileReader("input.json"));
121 | JSONObject jsonObject = (JSONObject) obj;
122 | JSONArray timesheetArray = (JSONArray) jsonObject.get("timesheet");
123 |
124 | for (JSONObject object : (Iterable) timesheetArray) {
125 | double percent = Double.parseDouble((String) object.get("percentComplete"));
126 | percentages.add(percent);
127 | }
128 | } catch (ParseException | IOException e) {
129 | e.printStackTrace();
130 | }
131 | return percentages;
132 | }
133 |
134 | private Map createMembers(JSONObject milestone) {
135 | Map map = new HashMap<>();
136 |
137 | for (Object o : milestone.keySet()) {
138 | Integer key = Integer.valueOf((String) o);
139 | double value = Double.parseDouble((String) milestone.get(key.toString()));
140 | map.put(key, value);
141 | }
142 | return map;
143 | }
144 |
145 | //Reader and object creator for the risk matrix
146 | public ArrayList loadRiskMatrix(){
147 |
148 | JSONParser jsonParser = new JSONParser();
149 | ArrayList risks = new ArrayList<>();
150 |
151 | try{
152 | Object obj = jsonParser.parse(new FileReader("input.json"));
153 | JSONObject jsonObject = (JSONObject) obj;
154 |
155 | JSONArray milestoneArray = (JSONArray) jsonObject.get("riskMatrix");
156 |
157 | for (JSONObject object : (Iterable) milestoneArray) {
158 | String riskName = (String) object.get("riskName");
159 | String veryLikely = (String) object.get("veryLikely");
160 | String possible = (String) object.get("possible");
161 | String unlikely = (String) object.get("unlikely");
162 |
163 | RiskMatrix risk = new RiskMatrix(riskName, veryLikely, possible, unlikely);
164 | risks.add(risk);
165 | }
166 |
167 | } catch (ParseException | IOException e) {
168 | e.printStackTrace();
169 | }
170 | return risks;
171 |
172 | }
173 |
174 | }
--------------------------------------------------------------------------------
/src/json_reader_writer/JsonWriter.java:
--------------------------------------------------------------------------------
1 | package json_reader_writer;
2 |
3 | import member_manager.*;
4 | import org.json.simple.JSONArray;
5 | import org.json.simple.JSONObject;
6 |
7 | import java.io.*;
8 | import java.time.format.DateTimeFormatter;
9 | import java.util.Map;
10 |
11 | // Inspiration for logic of the json reader and writer comes from the following site:
12 | // https://stackabuse.com/reading-and-writing-json-in-java/
13 |
14 | public class JsonWriter {
15 |
16 | //Formatter to easily parse Date format to correct string format.
17 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-LL-dd");
18 |
19 | @SuppressWarnings("unchecked")
20 | public void savePlanner(Planner planner){
21 | JSONObject plannerObject = new JSONObject();
22 | plannerObject.put("projectName", planner.getProjectName());
23 | plannerObject.put("startDate", planner.getStartDate().format(formatter));
24 | plannerObject.put("endDate", planner.getEndDate().format((formatter)));
25 | plannerObject.put("budget", Double.toString(planner.getBudget()));
26 | JSONArray memberList = new JSONArray();
27 |
28 | for(Member member: planner.members){
29 | JSONObject memberDetails = new JSONObject();
30 | memberDetails.put("firstName", member.getFirstName());
31 | memberDetails.put("lastName", member.getLastName());
32 | memberDetails.put("ID", Integer.toString(member.getId()));
33 | memberDetails.put("salary", Double.toString(member.getSalary()));
34 | JSONArray timesheetList = new JSONArray();
35 |
36 | }
37 |
38 | JSONArray milestoneList = new JSONArray();
39 |
40 | for(Milestone milestone:planner.milestones){
41 | JSONObject milestoneDetails = new JSONObject();
42 | milestoneDetails.put("milestoneName", milestone.getMilestoneName());
43 | milestoneDetails.put("milestoneDescription", milestone.getMilestoneDescription());
44 | milestoneDetails.put("startDate", milestone.getStartDate().format(formatter));
45 | milestoneDetails.put("plannedEndDate", milestone.getPlannedEndDate().format(formatter));
46 | milestoneDetails.put("actualEndDate", milestone.getActualEndDate().format(formatter));
47 |
48 | JSONObject hoursWorkedDetails = new JSONObject();
49 | Map map = milestone.getEmployeeHours();
50 | for (Map.Entry entry : map.entrySet()) {
51 | hoursWorkedDetails.put(entry.getKey().toString(), entry.getValue().toString());
52 | }
53 |
54 | milestoneDetails.put("hoursPerMember", hoursWorkedDetails);
55 | milestoneList.add(milestoneDetails);
56 | plannerObject.put("milestones" ,milestoneList);
57 |
58 | }
59 |
60 |
61 | JSONArray riskMatrixList = new JSONArray();
62 |
63 | for(RiskMatrix riskMatrix : planner.risks){
64 | JSONObject riskMatrixDetails = new JSONObject();
65 | riskMatrixDetails.put("riskName", riskMatrix.getRiskName());
66 | riskMatrixDetails.put("veryLikely", riskMatrix.getVeryLikely());
67 | riskMatrixDetails.put("possible", riskMatrix.getPossible());
68 | riskMatrixDetails.put("unlikely", riskMatrix.getUnlikely());
69 | riskMatrixList.add(riskMatrixDetails);
70 | }
71 | plannerObject.put("riskMatrix", riskMatrixList);
72 |
73 |
74 | try (FileWriter file = new FileWriter("input.json")){
75 | file.write(plannerObject.toJSONString());
76 | file.flush();
77 | } catch (IOException e){
78 | e.printStackTrace();
79 | }
80 | }
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/src/member_manager/Member.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | import id_generator.GeneratorMain;
4 | import java.util.ArrayList;
5 |
6 | public class Member {
7 |
8 | private String firstName;
9 | private String lastName;
10 | private int id;
11 | private int dateOfBirth;
12 | private double salary;
13 | private ArrayList hoursWorked = new ArrayList<>();
14 |
15 | GeneratorMain idGen = new GeneratorMain();
16 |
17 | //constructor for a new employee where we need birthday to generate a new ID
18 | public Member (String firstName, String lastName, int dateOfBirth, double salary){
19 | this.firstName = firstName;
20 | this.lastName = lastName;
21 | this.dateOfBirth = dateOfBirth;
22 | this.salary = salary;
23 | this.id = loadID();
24 | }
25 | //constructor for an already existing employee where we have the ID already stored
26 | public Member (String firstName, String lastName, float ID, double salary ){
27 | this.firstName = firstName;
28 | this.lastName = lastName;
29 | this.id =(int) ID;
30 | this.salary = salary;
31 | }
32 |
33 | public String getFirstName() {
34 | return firstName;
35 | }
36 |
37 | public void setFirstName(String firstName) {
38 | this.firstName = firstName;
39 | }
40 |
41 | public String getLastName() {
42 | return lastName;
43 | }
44 |
45 | public void setLastName(String lastName) {
46 | this.lastName = lastName;
47 | }
48 |
49 | public int getId() {
50 | return id;
51 | }
52 |
53 | public void setID(int id) {
54 | this.id = id;
55 | }
56 |
57 | //generates a new ID based on names and birthday
58 | public int loadID() {
59 | id = idGen.generateID(this.firstName, this.lastName, this.dateOfBirth);
60 | return id;
61 | }
62 |
63 | public int getDateOfBirth() {
64 | return dateOfBirth;
65 | }
66 |
67 | public void setDateOfBirth(int date_of_birth) {
68 | this.dateOfBirth = dateOfBirth;
69 | }
70 |
71 | public double getSalary() {
72 | return salary;
73 | }
74 |
75 | public void setSalary(double salary) {
76 | this.salary = salary;
77 | }
78 |
79 | @Override
80 | public String toString() {
81 | return "Name: " + firstName + " " + lastName + '\n' +
82 | "ID: " + id + '\n' +
83 | "Birthday: " + dateOfBirth + '\n' +
84 | "Salary: " + salary + "/hour" + '\n';
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/member_manager/Milestone.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | import java.time.LocalDate;
4 | import java.util.Map;
5 |
6 | public class Milestone {
7 | private String milestoneName;
8 | private String milestoneDescription;
9 | private LocalDate startDate;
10 | private LocalDate plannedEndDate;
11 | private LocalDate actualEndDate;
12 | private Map employeeHours; //ID as the key, amount of hour as the value. ex. ID 1, hours 8
13 |
14 | public Milestone(String milestoneName, String milestoneDescription, LocalDate startDate, LocalDate plannedEndDate, LocalDate actualEndDate , Map employeeHours) {
15 | this.milestoneName = milestoneName;
16 | this.milestoneDescription = milestoneDescription;
17 | this.startDate = startDate;
18 | this.plannedEndDate = plannedEndDate;
19 | this.actualEndDate = actualEndDate;
20 | this.employeeHours = employeeHours;
21 | }
22 |
23 | public String getMilestoneName() {
24 | return milestoneName;
25 | }
26 |
27 | public LocalDate getStartDate() {
28 | return startDate;
29 | }
30 |
31 | public LocalDate getPlannedEndDate() {
32 | return plannedEndDate;
33 | }
34 |
35 | public LocalDate getActualEndDate() {
36 | return actualEndDate;
37 | }
38 |
39 | public Map getEmployeeHours() {
40 | return employeeHours;
41 | }
42 |
43 | public boolean isAccomplished(LocalDate today) {
44 | if(actualEndDate.isBefore(today)){
45 | return true;
46 | }
47 | return false;
48 | }
49 |
50 | public String getMilestoneDescription() {
51 | return milestoneDescription;
52 | }
53 |
54 |
55 |
56 | @Override
57 | public String toString() {
58 | return "{" +
59 | "Milestone : '" + milestoneName + '\'' +
60 | ", Milestone Description : '" + milestoneDescription + '\'' +
61 | ", Accomplished by ID : " + employeeHours +
62 | '}';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/member_manager/Planner.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | import json_reader_writer.JsonReader;
4 | import json_reader_writer.JsonWriter;
5 |
6 | import java.time.LocalDate;
7 | import java.time.temporal.ChronoUnit;
8 | import java.util.ArrayList;
9 | import java.util.Collections;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | public class Planner {
14 |
15 | // Hello gamers
16 |
17 | JsonReader reader = new JsonReader();
18 |
19 | private double budget;
20 | private String projectName;
21 | LocalDate startDate;
22 | LocalDate endDate;
23 | LocalDate localDate = LocalDate.now();
24 | private float totalDays;
25 | private float nowDays;
26 |
27 | public ArrayList members = loadMember();
28 | public ArrayList milestones = loadMilestones();
29 | public ArrayList risks = loadRiskMatrix();
30 | public Map> timesheet = loadTimesheet();
31 | public ArrayList percentComplete = loadPercentComplete();
32 |
33 |
34 | public Planner(String projectName, LocalDate startDate, LocalDate endDate, double budget) {
35 | this.projectName = projectName;
36 | this.startDate = startDate;
37 | this.endDate = endDate;
38 | this.budget = budget;
39 | this.totalDays = ChronoUnit.DAYS.between(startDate, endDate);
40 | this.nowDays = ChronoUnit.DAYS.between(startDate, localDate);
41 | }
42 |
43 |
44 | public double getAllHoursFromWeek(int week) { //Can be used in place of get hours from milestone
45 | double totalHours = 0;
46 | if (timesheet.containsKey(week)) {
47 | Map hoursMap = timesheet.get(week);
48 | for (Double value : hoursMap.values()) {
49 | totalHours = totalHours + value;
50 | }
51 | }
52 | return totalHours;
53 | }
54 |
55 | public double getAllHoursForMember(int searchID) {
56 | double totalHours = 0;
57 | for (Integer week : timesheet.keySet()) {
58 | Map hoursMap = timesheet.get(week);
59 | for (Integer memberID : hoursMap.keySet()) {
60 | if (searchID == memberID) {
61 | totalHours = totalHours + (Double.parseDouble(hoursMap.get(memberID).toString()));
62 | }
63 | }
64 | }
65 | return totalHours;
66 | }
67 |
68 | public double getWeeklyHoursForMember(int searchWeek, int searchID) {
69 | double totalHours = 0;
70 | if (timesheet.containsKey(searchWeek)) {
71 | Map week = timesheet.get(searchWeek);
72 | if (week.containsKey(searchID)) {
73 | totalHours = week.get(searchID);
74 | }
75 | }
76 | return totalHours;
77 | }
78 |
79 | public double getWeeklySalaryForMember(int searchWeek, int searchID) {
80 | boolean memberFound = false;
81 | double memberSalary = 0;
82 | double totalWeeklyMemberSalary = 0;
83 | for (Member member : members) {
84 | if (searchID == member.getId()) {
85 | memberFound = true;
86 | memberSalary = member.getSalary();
87 | }
88 | }
89 | if (memberFound) {
90 | double hoursWorked = getWeeklyHoursForMember(searchWeek, searchID);
91 | totalWeeklyMemberSalary = hoursWorked * memberSalary;
92 | }
93 | return totalWeeklyMemberSalary;
94 | }
95 |
96 | public double getTotalSalaryForMember(int searchID) {
97 | double totalMemberSalary = 0;
98 | for (Integer week : timesheet.keySet()) {
99 | double weeklySalary = getWeeklySalaryForMember(week, searchID);
100 | totalMemberSalary = totalMemberSalary + weeklySalary;
101 | }
102 | return totalMemberSalary;
103 | }
104 |
105 | public ArrayList getMilestonesWorkedOn(int id) {
106 | ArrayList milestonesWorkedOn = new ArrayList<>();
107 | for (Milestone milestone : milestones) {
108 | Map employeeHours = milestone.getEmployeeHours();
109 | if (employeeHours.containsKey(id) && (employeeHours.get(id) > 0)) {
110 | milestonesWorkedOn.add(milestone.getMilestoneName());
111 | }
112 | }
113 | return milestonesWorkedOn;
114 | }
115 |
116 |
117 | public int calcWeek() {
118 | int week = ((int) (nowDays/7)) + 1; //+1 is used to move the current week to the week we're currently on instead of weeks that have passed.
119 | return week;
120 | }
121 |
122 | public ArrayList calcPv(){
123 | ArrayList pcpValues = new ArrayList<>();
124 | int totalWeeks = (int) totalDays/7;
125 | for (int i = 0; i < totalWeeks; i++) {
126 | double pcp = (Math.round((budget/(totalWeeks-i))*100.00)/100.00);
127 | pcpValues.add(pcp);
128 | }
129 | return pcpValues;
130 | }
131 |
132 | public ArrayList calcEv(){
133 | ArrayList results = new ArrayList<>();
134 | for (int i = 0; i < percentComplete.size(); i++) {
135 | results.add((double) Math.round(((percentComplete.get(i) * budget)*100.00)/100.00));
136 | }
137 | return results;
138 | }
139 |
140 | public ArrayList calcSv(){ //ev-pv
141 | ArrayList results = new ArrayList<>();
142 | ArrayList evResults = calcEv();
143 | ArrayList pvResults = calcPv();
144 |
145 | for (int i = 0; i < pvResults.size(); i++) {
146 | double result = (Math.round(evResults.get(i) - pvResults.get(i))*100.00/100.00);
147 | results.add(result);
148 | }
149 | return results;
150 | }
151 |
152 | public ArrayList calcCv(){
153 | ArrayList results = new ArrayList<>();
154 | ArrayList avResults = calcActualCost();
155 | ArrayList evResults = calcEv();
156 |
157 | for (int i = 0; i < avResults.size(); i++) {
158 | double result = (Math.round(evResults.get(i) - avResults.get(i)*100.00)/100.00);
159 | results.add(result);
160 | }
161 | return results;
162 | }
163 |
164 | public ArrayList calcActualCost() {
165 | ArrayList actualCosts = new ArrayList<>();
166 | double weeklyCosts = 0;
167 |
168 | for (int i = 0; i < calcWeek(); i++) {
169 | for (Member member : members) {
170 | weeklyCosts = getWeeklySalaryForMember(i, member.getId());
171 | }
172 | actualCosts.add(weeklyCosts);
173 | weeklyCosts = 0;
174 | }
175 | return actualCosts;
176 | }
177 |
178 | public ArrayList calcSPI() {
179 | ArrayList results = new ArrayList<>();
180 | ArrayList evResults = calcEv();
181 | ArrayList pvResults = calcPv();
182 |
183 | for (int i = 0; i < pvResults.size(); i++) {
184 | double result = (evResults.get(i)/pvResults.get(i));
185 | results.add(result);
186 | }
187 | return results;
188 | }
189 |
190 | public ArrayList calcCPI() { //Values displayed are skewed due to not all hours input into the json file.
191 | ArrayList results = new ArrayList<>();
192 | ArrayList evResults = calcEv();
193 | ArrayList acResults = calcActualCost();
194 | double acResult = 0;
195 | double evResult = 0;
196 | double maxAcResult = Collections.max(acResults);
197 | double maxEvResult = Collections.max(evResults);
198 |
199 | for (int i = 0; i < acResults.size(); i++) {
200 | if (acResults.get(i) == 0) {
201 | acResult = maxEvResult;
202 | } else {
203 | acResult = acResults.get(i);
204 | }
205 | if (evResults.get(i) == 0) {
206 | evResult = maxAcResult;
207 | } else {
208 | evResult = evResults.get(i);
209 | }
210 |
211 | double result = (evResult/acResult);
212 | results.add(result);
213 | }
214 | return results;
215 | }
216 |
217 | public ArrayList calcBAC() {
218 | double totalSalaries = 0;
219 | ArrayList results = new ArrayList<>();
220 | for (int i = 0; i < calcWeek(); i++) {
221 | System.out.println(i);
222 | for (Member member : members) {
223 | totalSalaries = totalSalaries + getWeeklySalaryForMember(i+1, member.getId());
224 | }
225 | double result = budget - totalSalaries;
226 | results.add(result);
227 | }
228 |
229 | return results;
230 | }
231 |
232 | //method for creating a new member
233 | public void addMember(String firstName, String lastName, int dateOfBirth, double salary) {
234 | Member member = new Member(firstName, lastName, dateOfBirth, salary);
235 | members.add(member);
236 | }
237 | //method for creating a new milestone
238 | public void addMilestone(String milestoneName, String milestoneDescription, LocalDate startDate, LocalDate actualEndDate, LocalDate plannedEndDate, Map employeeHours) {
239 | Milestone milestone = new Milestone(milestoneName, milestoneDescription, startDate, actualEndDate, plannedEndDate , employeeHours);
240 | milestones.add(milestone);
241 | }
242 |
243 | public void addRisks(String riskName, String veryLikely, String possible, String unlikely){
244 | RiskMatrix risk = new RiskMatrix(riskName, veryLikely, possible, unlikely);
245 | risks.add(risk);
246 | }
247 |
248 |
249 | public ArrayList loadMember(){
250 | return reader.loadMember();
251 | }
252 |
253 | public ArrayList loadMilestones(){
254 | return reader.loadMilestone();
255 | }
256 |
257 | public ArrayList loadRiskMatrix(){
258 | return reader.loadRiskMatrix();
259 | }
260 |
261 | public Map> loadTimesheet() {
262 | return reader.loadTimesheet();
263 | };
264 |
265 | public ArrayList loadPercentComplete() {
266 | return reader.percentComplete();
267 | }
268 |
269 | public double getBudget() {
270 | return budget;
271 | }
272 |
273 | public String getProjectName() {
274 | return projectName;
275 | }
276 |
277 | public LocalDate getStartDate() {
278 | return startDate;
279 | }
280 |
281 | public LocalDate getEndDate() {
282 | return endDate;
283 | }
284 |
285 | public ArrayList getMembers() {
286 | return members;
287 | }
288 |
289 | public ArrayList getMilestones() {
290 | return milestones;
291 | }
292 |
293 | public ArrayList getRisks() {
294 | return risks;
295 | }
296 |
297 | @Override
298 | public String toString() {
299 | return "Name: " + projectName + "\n" +
300 | "StartDate: " + startDate + "\n" +
301 | "EndDate: " + endDate + "\n";
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/src/member_manager/RiskMatrix.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | public class RiskMatrix {
4 | private String riskName;
5 | private String veryLikely;
6 | private String possible;
7 | private String unlikely;
8 |
9 | public RiskMatrix(String riskName, String veryLikely, String possible, String unlikely){
10 | this.riskName = riskName;
11 | this.veryLikely = veryLikely;
12 | this.possible = possible;
13 | this.unlikely = unlikely;
14 | }
15 |
16 |
17 | public String getRiskName() { return riskName; }
18 |
19 | public void setRiskName(String riskName) { this.riskName = riskName; }
20 |
21 | public String getVeryLikely() { return veryLikely; }
22 |
23 | public void setVeryLikely(String veryLikely) { this.veryLikely = veryLikely; }
24 |
25 | public String getPossible() { return possible; }
26 |
27 | public void setPossible(String possible) { this.possible = possible; }
28 |
29 | public String getUnlikely() { return unlikely; }
30 |
31 | public void setUnlikely(String unlikely) { this.unlikely = unlikely; }
32 |
33 |
34 |
35 | }
--------------------------------------------------------------------------------
/src/member_manager/Schedule.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | import javafx.beans.property.SimpleStringProperty;
4 |
5 | import java.time.LocalDate;
6 |
7 | public class Schedule {
8 |
9 | private SimpleStringProperty id;
10 | private SimpleStringProperty task;
11 | private LocalDate startDate;
12 | private LocalDate finishDate;
13 | private SimpleStringProperty duration;
14 | private SimpleStringProperty resources;
15 |
16 | public Schedule(String id, String task, LocalDate startDate, LocalDate finishDate, String duration, String resources){
17 |
18 | this.id = new SimpleStringProperty(id);
19 | this.task = new SimpleStringProperty(task);
20 | this.startDate = startDate;
21 | this.finishDate = finishDate;
22 | this.duration = new SimpleStringProperty(duration);
23 | this.resources = new SimpleStringProperty(resources);
24 | }
25 |
26 |
27 | public String getTask() {
28 | return task.get();
29 | }
30 |
31 | public SimpleStringProperty taskProperty() {
32 | return task;
33 | }
34 |
35 | public void setTask(String task) {
36 | this.task.set(task);
37 | }
38 |
39 | public LocalDate getStartDate() {
40 | return startDate;
41 | }
42 |
43 | public void setStartDate(LocalDate startDate) {
44 | this.startDate = startDate;
45 | }
46 |
47 | public LocalDate getFinishDate() {
48 | return finishDate;
49 | }
50 |
51 | public void setFinishDate(LocalDate finishDate) {
52 | this.finishDate = finishDate;
53 | }
54 |
55 | public String getDuration() {
56 | return duration.get();
57 | }
58 |
59 | public SimpleStringProperty durationProperty() {
60 | return duration;
61 | }
62 |
63 | public void setDuration(String duration) {
64 | this.duration.set(duration);
65 | }
66 |
67 | public String getResources() {
68 | return resources.get();
69 | }
70 |
71 | public SimpleStringProperty resourcesProperty() {
72 | return resources;
73 | }
74 |
75 | public void setResources(String resources) {
76 | this.resources.set(resources);
77 | }
78 |
79 | public String getId() {
80 | return id.get();
81 | }
82 |
83 | public SimpleStringProperty idProperty() {
84 | return id;
85 | }
86 |
87 | public void setId(String id) {
88 | this.id.set(id);
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/member_manager/Timesheet.java:
--------------------------------------------------------------------------------
1 | package member_manager;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Map;
5 |
6 | public class Timesheet {
7 | private Map> weeks; //dont touch
8 |
9 | public Timesheet(Map> weeks) {
10 | this.weeks = weeks;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/sample/Main.java:
--------------------------------------------------------------------------------
1 | package sample;
2 |
3 | import javafx.application.Application;
4 | import javafx.fxml.FXMLLoader;
5 | import javafx.scene.Parent;
6 | import javafx.scene.Scene;
7 | import javafx.stage.Stage;
8 | import json_reader_writer.JsonReader;
9 | import org.json.simple.parser.ParseException;
10 |
11 | import java.io.IOException;
12 |
13 | public class Main extends Application {
14 |
15 | private static JsonReader reader = new JsonReader();
16 |
17 | @Override
18 | public void start(Stage primaryStage) throws Exception{
19 | Parent root = FXMLLoader.load(getClass().getResource("../fxml-files/dashboard.fxml"));
20 | primaryStage.setTitle("Group 13's Project Manager");
21 | primaryStage.setScene(new Scene(root, 800, 500));
22 | primaryStage.show();
23 |
24 | }
25 |
26 | public static void main(String[] args) throws IOException, ParseException {
27 | launch(args);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/sample/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | height: 100%;
3 | width: 100%;
4 | background-image: linear-gradient(to bottom right, #b4b4b4, #4bb4bb);
5 | background-repeat: no-repeat;
6 | }
7 |
8 | .main-bar {
9 | font-size: 3em;
10 | color: #3e3e3e;
11 | text-shadow: 3px 2px 5px #4bb4bb;
12 | float: left;
13 | padding-bottom: 25px;
14 | margin-bottom: 30px;
15 | }
16 |
17 | .id-search-bar {
18 | float: left;
19 | padding-top: 50px;
20 | }
21 |
22 | .about-member {
23 | float: right;
24 | padding-top: 50px;
25 | }
26 |
27 | * {
28 | box-sizing: border-box;
29 | }
30 |
31 | form.id-search-form input[type=text]{
32 | padding: 10px;
33 | font-size: 15px;
34 | border: 1px solid gray;
35 | float: left;
36 | width: 40%;
37 | background: #b4b4b4;
38 | }
39 |
40 | form.id-search-form button {
41 | float: left;
42 | padding: 10px;
43 | background: #4bb4bb;
44 | color: white;
45 | border: 1px solid gray;
46 | border-left: none;
47 | cursor: pointer;
48 | }
49 |
50 | form.id-search-form button:hover {
51 | background-color: #44a4aa;
52 | }
53 |
54 | form.id-search-form::after {
55 | content: "";
56 | clear: both;
57 | display: table;
58 | }
59 |
60 | .member-table-display {
61 | width: 80%;
62 | box-shadow: 8px 8px 3px rgba(0, 0, 0, 0.25);
63 | }
64 |
65 | .about-member {
66 | padding-right: 20px;
67 | height: 450px;
68 | overflow: auto;
69 | box-shadow: -8px 8px 3px rgba(0, 0, 0, 0.25);
70 | }
71 |
72 | .personIcon {
73 | width: 100px;
74 | }
75 |
76 | .search-bar-dropdown {
77 | padding: 0;
78 | margin-bottom: 35px;
79 | width: 80%;
80 | background: #4bb4bb;
81 | border-top: none;
82 | box-shadow: 2px 2px 1px rgba(0, 0, 0, 0.25);
83 | }
84 |
85 | .search-bar-dropdown button {
86 | width: 100%;
87 | text-align: center;
88 | padding: 5px;
89 | color: white;
90 | border: 1px solid gray;
91 | border-top: none;
92 | }
93 |
94 | .dropdown-menu {
95 | border-bottom: 2px solid #bbbbbb;
96 | }
--------------------------------------------------------------------------------