From c1bf32460f6570d8f37b75d1b7211677f0ec7709 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 23:31:41 -0400 Subject: [PATCH 01/45] Added initial file to test the save function, and added a Team object, to provide something to save --- src/main/Team.java | 65 ++++++++++++++++++++++++++++++++++++++ src/test/SaveTeamTest.java | 24 ++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/main/Team.java create mode 100644 src/test/SaveTeamTest.java diff --git a/src/main/Team.java b/src/main/Team.java new file mode 100644 index 0000000..bddd714 --- /dev/null +++ b/src/main/Team.java @@ -0,0 +1,65 @@ +/** + * + */ +package main; + +/** + * @author Bryan Culver + * + */ +public class Team { + + private String teamName; + private String teamLocation; + + /** + * Constructor that builds an empty team + */ + public Team(){ + this.teamName = " "; + this.teamLocation = " "; + } + + public Team(String location, String name) { + this.teamName = name; + this.teamLocation = location; + } + + /** + * Method that writes data in the form of a JSON to a file + */ + public boolean saveTeam() { + //code to save the team's info + return true; + } + + /** + * Method to load the team from specified location. + */ + public boolean loadTeam() { + // code to load team info from file to memory. + return true; + } + + public String toString() { + return (teamLocation + " " + teamName); + } + + public boolean setTeamName(String newName) { + teamName = newName; + return true; + } + + public boolean setTeamLocation(String newLocation) { + teamLocation = newLocation; + return true; + } + + public String getTeamName() { + return teamName; + } + + public String getTeamLocation() { + return teamLocation; + } +} diff --git a/src/test/SaveTeamTest.java b/src/test/SaveTeamTest.java new file mode 100644 index 0000000..99fe84f --- /dev/null +++ b/src/test/SaveTeamTest.java @@ -0,0 +1,24 @@ +/** + * + */ +package test; + +import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; + +/** + * @author Bryan Culver + * + */ +class SaveTeamTest { + + @BeforeAll + void TeamSetup() { + + } + + @Test + void TeamSaveTest(){ + + } +} From b16fe7caac445d4c543fdad74465469da081d8c1 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 25 Sep 2023 21:08:45 -0400 Subject: [PATCH 02/45] created tests and basic Team class for the basis of the app --- src/test/{CreateTeamTest.java => TeamTest.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/{CreateTeamTest.java => TeamTest.java} (100%) diff --git a/src/test/CreateTeamTest.java b/src/test/TeamTest.java similarity index 100% rename from src/test/CreateTeamTest.java rename to src/test/TeamTest.java From b52b3786397dc59f40a947822b2b07d5f1e076c9 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 25 Sep 2023 21:10:41 -0400 Subject: [PATCH 03/45] committing the rest of the files changed --- build.gradle | 6 ++++-- src/test/SaveTeamTest.java | 24 ------------------------ src/test/TeamTest.java | 23 ++++++++++++++++++----- 3 files changed, 22 insertions(+), 31 deletions(-) delete mode 100644 src/test/SaveTeamTest.java diff --git a/build.gradle b/build.gradle index e2145c1..8a10513 100644 --- a/build.gradle +++ b/build.gradle @@ -1,2 +1,4 @@ -apply plugin: 'java' -apply plugin: 'eclipse' \ No newline at end of file +plugins{ + id 'java' + id 'eclipse' +} \ No newline at end of file diff --git a/src/test/SaveTeamTest.java b/src/test/SaveTeamTest.java deleted file mode 100644 index 99fe84f..0000000 --- a/src/test/SaveTeamTest.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * - */ -package test; - -import org.junit.Test; -import org.junit.jupiter.api.BeforeAll; - -/** - * @author Bryan Culver - * - */ -class SaveTeamTest { - - @BeforeAll - void TeamSetup() { - - } - - @Test - void TeamSaveTest(){ - - } -} diff --git a/src/test/TeamTest.java b/src/test/TeamTest.java index 4cc9c37..d4772f4 100644 --- a/src/test/TeamTest.java +++ b/src/test/TeamTest.java @@ -21,20 +21,26 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import main.Team; + /** * @author "Bryan Culver" * */ -class CreateTeamTest { - +class TeamTest { + Team teamTestA; + Team teamTestB; /** * @throws java.lang.Exception */ @BeforeAll static void setUpBeforeClass() throws Exception { - //view = new TeamBuildingView("Test Build"); + Team teamTestA = new Team(); + assertEquals(" ", teamTestA.toString()); + Team teamTestB = new Team("Detroit", "Red_Wings"); + assertEquals("Detroit Red_Wings", teamTestB.toString()); } /** @@ -60,8 +66,15 @@ void tearDown() throws Exception { } @Test - void test() { - fail("Not yet implemented"); + void testTeamCreation() { + assertTrue(this.teamTestA!=null); + assertEquals("Detroit", teamTestB.getTeamLocation()); + assertEquals("Red_Wings", teamTestB.getTeamName()); + + teamTestA.setTeamLocation("Buffalo"); + teamTestB.setTeamName("Sabers"); + assertEquals("Buffalo", teamTestA.getTeamLocation()); + assertEquals("Sabers", teamTestA.getTeamName()); } } From 18a674f4571b7acf63a1e6b435356ac45d57e9e6 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 21:11:06 -0400 Subject: [PATCH 04/45] continuing to do work on the gradle file. --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 8a10513..7721093 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,10 @@ plugins{ id 'java' id 'eclipse' + id 'jacoco' +} + +test { + useJUnitPlatform() + finalizedBy jacocoTestReport } \ No newline at end of file From 9b65a30907c686feb22930963d676ab3214153b2 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 6 Oct 2023 21:39:26 -0400 Subject: [PATCH 05/45] made changes to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a41885d..0cbb009 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ hs_err_pid* .project .settings/ .classpath +/bin/ From 7db76edda5f4cce1ba399bdcc56a7092e31c2f3d Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 7 Apr 2023 16:44:55 -0400 Subject: [PATCH 06/45] implemented the new GridBagConstraintsObject and all labels are in place. Signed-off-by: Bryan Culver --- src/view/TeamBuildingView.java | 36 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/view/TeamBuildingView.java b/src/view/TeamBuildingView.java index 30f7573..f93b910 100644 --- a/src/view/TeamBuildingView.java +++ b/src/view/TeamBuildingView.java @@ -1,11 +1,12 @@ package view; import java.awt.Dimension; +import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JButton; import javax.swing.JFrame; -import javax.swing.JTextField; +//import javax.swing.JTextField; import util.GridBagConstraintsObject; @@ -18,30 +19,43 @@ public class TeamBuildingView extends JFrame{ */ private static final long serialVersionUID = 1L; private JButton doneButton; - private JTextField teamTitleTF; - private JLabel teamTitleLabel = new JLabel("Team Title"); + //private JTextField teamTitleTF; + private JLabel teamTitleLabel; private JPanel panel; public TeamBuildingView(String title) { super(title); - teamTitleTF = new JTextField("Team Title"); + + GridBagLayout gbl = new GridBagLayout(); + panel = new JPanel(gbl); + + teamTitleLabel = new JLabel("Team Title"); doneButton = new JButton("DONE"); - panel = new JPanel(new GridBagLayout()); + GridBagConstraintsObject gbco = new GridBagConstraintsObject(); //5,5,5,5,0,0,0,1,null, 0,0 + gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); - panel.add(teamTitleTF, gbco); - panel.add(doneButton, gbco ); - panel.add(teamTitleLabel, gbco); + //owner name (username) + //Location + //hockey team title + //Stanley Cup wins + //Last Year's standing + panel.add(new JLabel("Owner's Name"),gbco.gridx(0).gridy(0)); + panel.add(new JLabel("Team's Location"), gbco.gridy(1).gridx(0)); + //panel.add(teamTitleTF, gbco.gridy(2)); + panel.add(teamTitleLabel, gbco.gridy(2)); + panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3)); + panel.add(new JLabel("Last Year's standing"), gbco.gridy(4)); + panel.add(doneButton, gbco.gridy(4).gridx(4).anchor(GridBagConstraints.LAST_LINE_END) ); this.getContentPane().add(panel); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(new Dimension(500,500)); - //this.pack(); + //this.pack(); } public void Close() { } - -} +} \ No newline at end of file From 35ae6f8d90d1099105f4c00f9786a96a491416da Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 14 Apr 2023 12:08:53 -0400 Subject: [PATCH 07/45] Meets requirements. Still refactoring. Signed-off-by: Bryan Culver --- src/view/TeamBuildingView.java | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/view/TeamBuildingView.java b/src/view/TeamBuildingView.java index f93b910..796d3a7 100644 --- a/src/view/TeamBuildingView.java +++ b/src/view/TeamBuildingView.java @@ -11,6 +11,7 @@ import util.GridBagConstraintsObject; import javax.swing.JPanel; +import javax.swing.JTextField; import javax.swing.JLabel; public class TeamBuildingView extends JFrame{ @@ -33,27 +34,27 @@ public TeamBuildingView(String title) { doneButton = new JButton("DONE"); - GridBagConstraintsObject gbco = new GridBagConstraintsObject(); //5,5,5,5,0,0,0,1,null, 0,0 + GridBagConstraintsObject gbco = new GridBagConstraintsObject(); gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); - //owner name (username) - //Location - //hockey team title - //Stanley Cup wins - //Last Year's standing panel.add(new JLabel("Owner's Name"),gbco.gridx(0).gridy(0)); panel.add(new JLabel("Team's Location"), gbco.gridy(1).gridx(0)); - //panel.add(teamTitleTF, gbco.gridy(2)); - panel.add(teamTitleLabel, gbco.gridy(2)); - panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3)); - panel.add(new JLabel("Last Year's standing"), gbco.gridy(4)); - panel.add(doneButton, gbco.gridy(4).gridx(4).anchor(GridBagConstraints.LAST_LINE_END) ); + panel.add(teamTitleLabel, gbco.gridy(2).gridx(0)); + panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3).gridx(0)); + panel.add(new JLabel("Last Year's standing"), gbco.gridy(4).gridx(0)); + + panel.add(new JTextField("username"),gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL)); + panel.add(new JTextField("City, State"), gbco.gridx(1).gridy(1)); + panel.add(new JTextField("Team Name"), gbco.gridx(1).gridy(2)); + panel.add(new JTextField("0"), gbco.gridx(1).gridy(3)); + panel.add(new JTextField("12"), gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); + + panel.add(doneButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END)); this.getContentPane().add(panel); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(new Dimension(500,500)); - //this.pack(); } public void Close() { From 5d46db397fcb54d001521923f0e29633a780e781 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 14 Apr 2023 14:57:39 -0400 Subject: [PATCH 08/45] Customized the appearance of the window, and established a custom 'JTextArea' class that uses my default settings. Also, removed method 'Close' since it did nothing and I changed the 'Done' button to 'Save'. Finished refactoring within scope. Signed-off-by: Bryan Culver --- src/test/CreateTeamTest.java | 5 ++-- src/view/HockeyViewTextArea.java | 35 ++++++++++++++++++++++++++ src/view/TeamBuildingView.java | 42 ++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 src/view/HockeyViewTextArea.java diff --git a/src/test/CreateTeamTest.java b/src/test/CreateTeamTest.java index ce636f1..4cc9c37 100644 --- a/src/test/CreateTeamTest.java +++ b/src/test/CreateTeamTest.java @@ -21,14 +21,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import view.TeamBuildingView; /** * @author "Bryan Culver" * */ class CreateTeamTest { - private static TeamBuildingView view; + /** * @throws java.lang.Exception @@ -43,7 +42,7 @@ static void setUpBeforeClass() throws Exception { */ @AfterAll static void tearDownAfterClass() throws Exception { - view.Close(); + } /** diff --git a/src/view/HockeyViewTextArea.java b/src/view/HockeyViewTextArea.java new file mode 100644 index 0000000..e1e906d --- /dev/null +++ b/src/view/HockeyViewTextArea.java @@ -0,0 +1,35 @@ +/** + * + */ +package view; + +import java.awt.Color; + +import javax.swing.JTextArea; + +/**A class to implement default style for JTextArea Components. + * @author "Bryan Culver" + * @version 14 April 2023 + */ +@SuppressWarnings("serial") +public class HockeyViewTextArea extends JTextArea { + + /** + * Constructor takes the String to be displayed, and the desired background Color + * @param msg + * @param background + */ + public HockeyViewTextArea(String msg, Color background) { + super(msg); + setDefaultSettings(background); + } + + /** + * A private class to set the settings for this JTextArea. + * @param background + */ + private void setDefaultSettings(Color background) { + this.setBackground(background); + this.setEditable(false); + } +} diff --git a/src/view/TeamBuildingView.java b/src/view/TeamBuildingView.java index 796d3a7..bb5052b 100644 --- a/src/view/TeamBuildingView.java +++ b/src/view/TeamBuildingView.java @@ -1,17 +1,15 @@ package view; -import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; +import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; -//import javax.swing.JTextField; import util.GridBagConstraintsObject; import javax.swing.JPanel; -import javax.swing.JTextField; import javax.swing.JLabel; public class TeamBuildingView extends JFrame{ @@ -19,10 +17,8 @@ public class TeamBuildingView extends JFrame{ * */ private static final long serialVersionUID = 1L; - private JButton doneButton; - //private JTextField teamTitleTF; - private JLabel teamTitleLabel; private JPanel panel; + private ActionListener saveListener; // TODO Implement listener class in main package. public TeamBuildingView(String title) { super(title); @@ -30,9 +26,18 @@ public TeamBuildingView(String title) { GridBagLayout gbl = new GridBagLayout(); panel = new JPanel(gbl); - teamTitleLabel = new JLabel("Team Title"); - doneButton = new JButton("DONE"); + JLabel teamTitleLabel = new JLabel("Team Title"); + JButton saveButton = new JButton("Save"); + JButton editButton = new JButton("Edit"); + int cupWins = 0; // TODO implement a get method for this. + int standingLastYear = 12; // TODO implement a get method for this. + // Implemented a HockeyViewTextArea class to avoid repeating changes to the JTextAreas. + HockeyViewTextArea cupWinsTA = new HockeyViewTextArea(Integer.toString(cupWins),this.getBackground()); + HockeyViewTextArea standingTA = new HockeyViewTextArea(Integer.toString(standingLastYear), this.getBackground()); + HockeyViewTextArea userNameTA = new HockeyViewTextArea("username", this.getBackground()); + HockeyViewTextArea locationTA = new HockeyViewTextArea("City, State", this.getBackground()); + HockeyViewTextArea teamNameTA = new HockeyViewTextArea("Team Name", this.getBackground()); GridBagConstraintsObject gbco = new GridBagConstraintsObject(); gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); @@ -43,20 +48,21 @@ public TeamBuildingView(String title) { panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3).gridx(0)); panel.add(new JLabel("Last Year's standing"), gbco.gridy(4).gridx(0)); - panel.add(new JTextField("username"),gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL)); - panel.add(new JTextField("City, State"), gbco.gridx(1).gridy(1)); - panel.add(new JTextField("Team Name"), gbco.gridx(1).gridy(2)); - panel.add(new JTextField("0"), gbco.gridx(1).gridy(3)); - panel.add(new JTextField("12"), gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); + panel.add(userNameTA,gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL).weightx(0.6)); + panel.add(locationTA, gbco.gridx(1).gridy(1)); + panel.add(teamNameTA, gbco.gridx(1).gridy(2)); + panel.add(cupWinsTA, gbco.gridx(1).gridy(3)); + panel.add(standingTA, gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); + + panel.add(editButton, gbco.gridx(0).gridy(5).anchor(GridBagConstraints.LAST_LINE_START).fill(0)); + panel.add(saveButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END).weightx(0)); + + saveButton.addActionListener(saveListener); // TODO Implement listener class in main package - panel.add(doneButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END)); this.getContentPane().add(panel); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); - this.setSize(new Dimension(500,500)); - } - - public void Close() { + this.pack(); } } \ No newline at end of file From d522d6b007eb4687e208242d1f644e330ca807c6 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 10:14:56 -0400 Subject: [PATCH 09/45] Added comments to Main.java Signed-off-by: Bryan Culver --- src/main/Main.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/Main.java b/src/main/Main.java index 59227b1..fd2d53d 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,7 +1,15 @@ +/** + * This is the Main view for the Team building Interface window. + */ package main; import view.TeamBuildingView; +/** + * + * @author "Bryan Culver" + * + */ public class Main { public static void main(String[] args) { From 60c75e56f1687764046c7e9d1728eecf0767563c Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 12:27:59 -0400 Subject: [PATCH 10/45] this is a required commit message Signed-off-by: Bryan Culver --- .gitignore | 3 +++ src/main/Main.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 0cbb009..be8adef 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ hs_err_pid* .settings/ .classpath /bin/ + +# local Gradle files +.gradle/ \ No newline at end of file diff --git a/src/main/Main.java b/src/main/Main.java index fd2d53d..e1ccb6e 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -12,6 +12,10 @@ */ public class Main { + /** + * The main method that runs the app to open the first view. + * @param args + */ public static void main(String[] args) { run(); } From 5bbca42ba9ae2661bc8f7dc680051cea8923faab Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 13:39:55 -0400 Subject: [PATCH 11/45] Added gradle, working on tests and tasks --- .gitignore | 2 +- .gradle/7.4.2/checksums/checksums.lock | Bin 0 -> 17 bytes .../dependencies-accessors.lock | Bin 0 -> 17 bytes .gradle/7.4.2/dependencies-accessors/gc.properties | 0 .../7.4.2/executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .gradle/7.4.2/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/7.4.2/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .gradle/7.4.2/gc.properties | 0 .gradle/8.3/checksums/checksums.lock | Bin 0 -> 17 bytes .../dependencies-accessors.lock | Bin 0 -> 17 bytes .gradle/8.3/dependencies-accessors/gc.properties | 0 .gradle/8.3/executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .gradle/8.3/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/8.3/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .gradle/8.3/gc.properties | 0 .gradle/buildOutputCleanup/buildOutputCleanup.lock | Bin 0 -> 17 bytes .gradle/buildOutputCleanup/cache.properties | 2 ++ .gradle/vcs-1/gc.properties | 0 build.gradle | 2 ++ 19 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .gradle/7.4.2/checksums/checksums.lock create mode 100644 .gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock create mode 100644 .gradle/7.4.2/dependencies-accessors/gc.properties create mode 100644 .gradle/7.4.2/executionHistory/executionHistory.lock create mode 100644 .gradle/7.4.2/fileChanges/last-build.bin create mode 100644 .gradle/7.4.2/fileHashes/fileHashes.lock create mode 100644 .gradle/7.4.2/gc.properties create mode 100644 .gradle/8.3/checksums/checksums.lock create mode 100644 .gradle/8.3/dependencies-accessors/dependencies-accessors.lock create mode 100644 .gradle/8.3/dependencies-accessors/gc.properties create mode 100644 .gradle/8.3/executionHistory/executionHistory.lock create mode 100644 .gradle/8.3/fileChanges/last-build.bin create mode 100644 .gradle/8.3/fileHashes/fileHashes.lock create mode 100644 .gradle/8.3/gc.properties create mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 .gradle/buildOutputCleanup/cache.properties create mode 100644 .gradle/vcs-1/gc.properties create mode 100644 build.gradle diff --git a/.gitignore b/.gitignore index be8adef..70da668 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ hs_err_pid* /bin/ # local Gradle files -.gradle/ \ No newline at end of file +.gradle/ diff --git a/.gradle/7.4.2/checksums/checksums.lock b/.gradle/7.4.2/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..895085f15b40b694bd857e6ca128269a3c345e9d GIT binary patch literal 17 TcmZSXd2)JZIUzlSzF!0~7!NF75-Q literal 0 HcmV?d00001 diff --git a/.gradle/8.3/dependencies-accessors/gc.properties b/.gradle/8.3/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/8.3/executionHistory/executionHistory.lock b/.gradle/8.3/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..4cc43b44e382224add20337ab1819858d7bff4ed GIT binary patch literal 17 TcmZSnOV literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..669d7e7 --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Fri Sep 22 13:31:26 EDT 2023 +gradle.version=8.3 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e2145c1 --- /dev/null +++ b/build.gradle @@ -0,0 +1,2 @@ +apply plugin: 'java' +apply plugin: 'eclipse' \ No newline at end of file From a5a42df4188a400a13e3e15e5c7f976ec4bff9c7 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 16:31:06 -0400 Subject: [PATCH 12/45] did some work in gradle and added gradle files to .gitignore Signed-off-by: Bryan Culver --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 70da668..ff9e3e3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ # BlueJ files *.ctxt +### Gradle ### +.gradle +/build/ + # Mobile Tools for Java (J2ME) .mtj.tmp/ From 18d59f8ca72989812e102ed59defd54e4ae7a51e Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 16:36:51 -0400 Subject: [PATCH 13/45] Droped files from .gitignore Signed-off-by: Bryan Culver --- .gradle/7.4.2/checksums/checksums.lock | Bin 17 -> 0 bytes .../dependencies-accessors.lock | Bin 17 -> 0 bytes .gradle/7.4.2/dependencies-accessors/gc.properties | 0 .../7.4.2/executionHistory/executionHistory.lock | Bin 17 -> 0 bytes .gradle/7.4.2/fileChanges/last-build.bin | Bin 1 -> 0 bytes .gradle/7.4.2/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .gradle/7.4.2/gc.properties | 0 .gradle/8.3/checksums/checksums.lock | Bin 17 -> 0 bytes .../dependencies-accessors.lock | Bin 17 -> 0 bytes .gradle/8.3/dependencies-accessors/gc.properties | 0 .gradle/8.3/executionHistory/executionHistory.lock | Bin 17 -> 0 bytes .gradle/8.3/fileChanges/last-build.bin | Bin 1 -> 0 bytes .gradle/8.3/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .gradle/8.3/gc.properties | 0 .gradle/buildOutputCleanup/buildOutputCleanup.lock | Bin 17 -> 0 bytes .gradle/buildOutputCleanup/cache.properties | 2 -- .gradle/vcs-1/gc.properties | 0 17 files changed, 2 deletions(-) delete mode 100644 .gradle/7.4.2/checksums/checksums.lock delete mode 100644 .gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock delete mode 100644 .gradle/7.4.2/dependencies-accessors/gc.properties delete mode 100644 .gradle/7.4.2/executionHistory/executionHistory.lock delete mode 100644 .gradle/7.4.2/fileChanges/last-build.bin delete mode 100644 .gradle/7.4.2/fileHashes/fileHashes.lock delete mode 100644 .gradle/7.4.2/gc.properties delete mode 100644 .gradle/8.3/checksums/checksums.lock delete mode 100644 .gradle/8.3/dependencies-accessors/dependencies-accessors.lock delete mode 100644 .gradle/8.3/dependencies-accessors/gc.properties delete mode 100644 .gradle/8.3/executionHistory/executionHistory.lock delete mode 100644 .gradle/8.3/fileChanges/last-build.bin delete mode 100644 .gradle/8.3/fileHashes/fileHashes.lock delete mode 100644 .gradle/8.3/gc.properties delete mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 .gradle/buildOutputCleanup/cache.properties delete mode 100644 .gradle/vcs-1/gc.properties diff --git a/.gradle/7.4.2/checksums/checksums.lock b/.gradle/7.4.2/checksums/checksums.lock deleted file mode 100644 index 895085f15b40b694bd857e6ca128269a3c345e9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 TcmZSXd2)JZIUzlSzF!0~7!NF75-Q diff --git a/.gradle/8.3/dependencies-accessors/gc.properties b/.gradle/8.3/dependencies-accessors/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/8.3/executionHistory/executionHistory.lock b/.gradle/8.3/executionHistory/executionHistory.lock deleted file mode 100644 index 4cc43b44e382224add20337ab1819858d7bff4ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 TcmZSnOV diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 669d7e7..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Sep 22 13:31:26 EDT 2023 -gradle.version=8.3 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties deleted file mode 100644 index e69de29..0000000 From ba6a1b2816587f69b112fbe216b8f8d48b12e865 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 21:26:51 -0400 Subject: [PATCH 14/45] Just added a new contributing file, hopefully this commit is signed. Signed-off-by: Bryan Culver --- CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e69de29 From 52f12618ce498910bef92b6ecae5296ca3448205 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 21:38:56 -0400 Subject: [PATCH 15/45] updates to the Contributing document Signed-off-by: Bryan Culver --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e69de29..5d1d6cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +h1 Contributing + +This project is open to contributions from anyone and is a participant in Hacktoberfest. \ No newline at end of file From 2d05e907771c81fe263044bda076fb94fd7c1027 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 21:55:02 -0400 Subject: [PATCH 16/45] making more changes Signed-off-by: Bryan Culver --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d1d6cf..18fb018 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,5 @@ h1 Contributing -This project is open to contributions from anyone and is a participant in Hacktoberfest. \ No newline at end of file +This project is open to contributions from anyone and is a participant in Hacktoberfest. + +more changes to be made \ No newline at end of file From 06419a252ef1b2ce980f7696ec40c1dc54468ff3 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 22:04:42 -0400 Subject: [PATCH 17/45] uni Signed-off-by: Bryan Culver --- CONTRIBUTING.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18fb018..5d1d6cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,3 @@ h1 Contributing -This project is open to contributions from anyone and is a participant in Hacktoberfest. - -more changes to be made \ No newline at end of file +This project is open to contributions from anyone and is a participant in Hacktoberfest. \ No newline at end of file From 76e8d24700c5e12a2564460ae6905ce7d668b740 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Tue, 3 Oct 2023 22:19:10 -0400 Subject: [PATCH 18/45] completed first draft of the CONTRIBUTING.md document Signed-off-by: Bryan Culver --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d1d6cf..e8eda50 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,49 @@ -h1 Contributing +# Contributing -This project is open to contributions from anyone and is a participant in Hacktoberfest. \ No newline at end of file +This project is open to contributions from anyone and is a participant in Hacktoberfest. + +Please pick from the issues something you would like to contribute. +If you think this project needs something that isn't addressed in the list of issues, please add it as an issue. + +Please read the README and review the license before contributing to this project. +Contributions that are considered out-of-scope may not be merged into the project. Make sure you are addressing an +existing issue, bug, or feature. If your work does not have an issue, bug, or feature, please create one with a well +defined scope. + +## Tests + +If you are contributing code, you should also contribute the unit tests you are using to test the performance of your code. + +If you are contributing code that is used in GUI, you do not need to submit tests. But if you feel inspired, any unit tests or GUI based testing framework will be accepted if it is well implemented. + +## Commits + +Please sign your commits. Establishing a git signature and using it for each commit will improve tracibility in the code you create. + +GitHub has excellent documentation to help you learn how to sign your commits. + +There is a way to sign your commits without having to retype a password each time. +Visit for more about that. + +Pull requests that contain unsigned commits CANNOT be merged into development. + +## Pull Requests + +Leave a comment describing the changes in your pull request. Include the issue or bug this pull request is related to. + +Your pull request may not be immediately approved. During the month of October, this repo will be closely monitored, +but at other times, responses may be slow. + +Your pull request approval may also be pending response comments from the maintainer's review. Please be patient and +understand that the maintainer is probably very confused and would mostly just like to learn from your contributed +skills. =D + +As part of your pull request, please add your name to the list of contributors below. + +Contributors: +________________________________ +|Name | GitHub | +|---------------|---------------| +|Bryan Culver | Bryan-Culver | +| | | +| | | \ No newline at end of file From d2045489a695193b87d918ee29b4e99e936baa14 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Sat, 7 Oct 2023 00:02:38 -0400 Subject: [PATCH 19/45] Made an adjustment to README and implemented a game screen view in order to run a game prediction. Signed-off-by: Bryan Culver --- README.md | 18 +++---- src/main/Main.java | 3 +- src/view/GameScreenView.java | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 src/view/GameScreenView.java diff --git a/README.md b/README.md index 333a19e..9c4add1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # HockeyApp An Educational Test-Driven exercise in Object-Oriented design using Java Swing. -This project gives you the task of managing a Hockey team using Java Swing, but it is really designed to practice -object-oriented design patterns with each added feature. The associated project also is organized to help facilitate -a Test-Driven Development approach. +This project gives you the opportunity to predict the result of a Hockey game using Java Swing, but it is really +designed to practice object-oriented design patterns with each added feature. The associated project also is organized +to help facilitate a Test-Driven Development approach. -Clone it, build it, run it, and click through some of the options available as a Team Owner. +Clone it, build it, run it, and run a few games. Then, when you understand **what** the app does, explore **how** the code is structured, and imagine new features you would like to add using classic and modern design patterns. @@ -23,18 +23,18 @@ Using your SSH key, enter the command `git clone git@github.com:Bryan-Culver/hoc If you're using HTTPS still, the command is `git clone https://github.com/Bryan-Culver/hockeyApp.git` in your terminal. ## Build It + Currently, this project is a simple Java Swing project. Use your IDE to compile the program with at least JavaSE-17. No other versions of Java have been tested at this time. As it is compiled, an executable is generated which will run -the app. +the app. ## Run It -When you run the app, you will see one Window that will display some basic amount of information about the team. +When you run the app, you will see one Window that will display inputs for the home team and away team. As this project grows, more screens and "Views" will be required and will eventually be available. ## Contributing -There will be a "Contributing.md" file provided within this repository as soon as this project is ready to take on -contributions. +Please reference the "Contributing.md" doc provided in this repository. You'll notice the **.gitignore** file has several file types that are specific to IDEs. Any additional files that your -editor will creat for metadata should be added to the **.gitignore** file. \ No newline at end of file +editor will create for metadata should be added to the **.gitignore** file. \ No newline at end of file diff --git a/src/main/Main.java b/src/main/Main.java index e1ccb6e..f421a24 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -4,6 +4,7 @@ package main; import view.TeamBuildingView; +import view.GameScreenView; /** * @@ -21,7 +22,7 @@ public static void main(String[] args) { } public static void run() { - TeamBuildingView view = new TeamBuildingView("The Fun Hockey App"); + GameScreenView view = new GameScreenView("The Fun Hockey App"); view.setVisible(true); } diff --git a/src/view/GameScreenView.java b/src/view/GameScreenView.java new file mode 100644 index 0000000..f7c62d2 --- /dev/null +++ b/src/view/GameScreenView.java @@ -0,0 +1,95 @@ +/** + * + */ +package view; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JComboBox; +import javax.swing.JButton; + +import util.GridBagConstraintsObject; + +/** + * @author Bryan Culver + * @version 7 October 2023 + */ +public class GameScreenView extends JFrame implements ActionListener{ + + Vector AwayTeamsList; + Vector HomeTeamsList; + //private JPanel jPanel; + public GameScreenView(String title) { + super(title); + GridBagLayout gbl = new GridBagLayout(); + JPanel panel = new JPanel(gbl); + JButton runButton = new JButton("Run Game Prediction"); + + HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", this.getBackground()); + HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", this.getBackground()); + + HomeTeamsList = new Vector<>(); + HomeTeamsList.add("Detroit Red Wings"); + HomeTeamsList.add("Chicago Black Hawks"); + HomeTeamsList.add("New York Rangers"); + + AwayTeamsList = new Vector<>(); + AwayTeamsList.add("Detroit Red Wings"); + AwayTeamsList.add("Chicago Black Hawks"); + AwayTeamsList.add("New York Rangers"); + + JComboBox HomeTeamSelection = new JComboBox(HomeTeamsList); + HomeTeamSelection.setName("Home"); + JComboBox AwayTeamSelection = new JComboBox(AwayTeamsList); + AwayTeamSelection.setName("Away"); + + HomeTeamSelection.addActionListener(this); + AwayTeamSelection.addActionListener(this); + + GridBagConstraintsObject gbco = new GridBagConstraintsObject(); + gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); + panel.add(HomeTeamLabel, gbco.gridx(0).gridy(0)); + panel.add(AwayTeamLabel, gbco.gridx(1)); + panel.add(HomeTeamSelection, gbco.gridx(0).gridy(1)); + panel.add(AwayTeamSelection, gbco.gridx(1)); + panel.add(runButton, gbco.gridy(3).anchor(GridBagConstraints.CENTER)); + + this.getContentPane().add(panel); + this.setLocationRelativeTo(null); + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + + this.pack(); + + } + + /** + * Action listener will remove the selected team from the other combo box + */ + @Override + public void actionPerformed(ActionEvent e) { + JComboBox cbSelected = (JComboBox)e.getSource(); + cbSelected.getModel(); + int selectedIndex = cbSelected.getSelectedIndex(); + if(cbSelected.getName().equalsIgnoreCase("Home")){ + // reset list for away team, minus the team selected for home. + AwayTeamsList.clear(); + AwayTeamsList.add(0, "Detroit Red Wings"); + AwayTeamsList.add(1, "Chicago Black Hawks"); + AwayTeamsList.add(2, "New York Rangers"); + AwayTeamsList.remove(selectedIndex); + }else if(cbSelected.getName().equalsIgnoreCase("Away")) { + // reset list for home team, minus the team selected for away. + HomeTeamsList.clear(); + HomeTeamsList.add(0, "Detroit Red Wings"); + HomeTeamsList.add(1, "Chicago Black Hawks"); + HomeTeamsList.add(2, "New York Rangers"); + HomeTeamsList.remove(selectedIndex); + } + } +} From 8a0282cbbe22daea3019ec3a283eac75a8e18a08 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Sat, 11 Nov 2023 23:09:55 -0500 Subject: [PATCH 20/45] Restructured for Gradle, and improved welcome screen. --- .gitignore | 1 + src/main/{ => java/launch}/Main.java | 6 +- .../java}/util/GridBagConstraintsObject.java | 2 +- src/{ => main/java}/view/GameScreenView.java | 65 +++++++++++++------ .../java}/view/HockeyViewTextArea.java | 2 +- .../java}/view/TeamBuildingView.java | 4 +- src/test/{ => java/main}/CreateTeamTest.java | 4 +- .../util}/GridBagConstraintsObjectTest.java | 4 +- 8 files changed, 55 insertions(+), 33 deletions(-) rename src/main/{ => java/launch}/Main.java (79%) rename src/{ => main/java}/util/GridBagConstraintsObject.java (99%) rename src/{ => main/java}/view/GameScreenView.java (55%) rename src/{ => main/java}/view/HockeyViewTextArea.java (96%) rename src/{ => main/java}/view/TeamBuildingView.java (97%) rename src/test/{ => java/main}/CreateTeamTest.java (95%) rename src/test/{ => java/util}/GridBagConstraintsObjectTest.java (98%) diff --git a/.gitignore b/.gitignore index ff9e3e3..e7ce5b2 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ hs_err_pid* # local Gradle files .gradle/ +.metadata/ diff --git a/src/main/Main.java b/src/main/java/launch/Main.java similarity index 79% rename from src/main/Main.java rename to src/main/java/launch/Main.java index f421a24..29959db 100644 --- a/src/main/Main.java +++ b/src/main/java/launch/Main.java @@ -1,10 +1,10 @@ /** * This is the Main view for the Team building Interface window. */ -package main; +package main.java.launch; -import view.TeamBuildingView; -import view.GameScreenView; +//import main.java.view.TeamBuildingView; +import main.java.view.GameScreenView; /** * diff --git a/src/util/GridBagConstraintsObject.java b/src/main/java/util/GridBagConstraintsObject.java similarity index 99% rename from src/util/GridBagConstraintsObject.java rename to src/main/java/util/GridBagConstraintsObject.java index 02f76a0..3b0b212 100644 --- a/src/util/GridBagConstraintsObject.java +++ b/src/main/java/util/GridBagConstraintsObject.java @@ -1,7 +1,7 @@ /** * */ -package util; +package main.java.util; import java.awt.GridBagConstraints; import java.awt.Insets; diff --git a/src/view/GameScreenView.java b/src/main/java/view/GameScreenView.java similarity index 55% rename from src/view/GameScreenView.java rename to src/main/java/view/GameScreenView.java index f7c62d2..0d4c7ee 100644 --- a/src/view/GameScreenView.java +++ b/src/main/java/view/GameScreenView.java @@ -1,20 +1,20 @@ /** * */ -package view; +package main.java.view; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Vector; +import java.util.Vector; // TODO: transition from Vector to ArrayList - bottleneck: JComboBox. import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JComboBox; import javax.swing.JButton; -import util.GridBagConstraintsObject; +import main.java.util.GridBagConstraintsObject; /** * @author Bryan Culver @@ -22,14 +22,24 @@ */ public class GameScreenView extends JFrame implements ActionListener{ + /** + * + */ + private static final long serialVersionUID = 1L; // required for serializable class. Vector AwayTeamsList; Vector HomeTeamsList; + JButton runButton; + HockeyViewTextArea results= new HockeyViewTextArea("The winner is...", this.getBackground()); //private JPanel jPanel; public GameScreenView(String title) { super(title); GridBagLayout gbl = new GridBagLayout(); JPanel panel = new JPanel(gbl); - JButton runButton = new JButton("Run Game Prediction"); + runButton = new JButton("Run Game Prediction"); + + runButton.addActionListener(this); + // TODO: the game can be implemented here. + //runButton.addActionListener(StartGame); HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", this.getBackground()); HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", this.getBackground()); @@ -60,6 +70,8 @@ public GameScreenView(String title) { panel.add(AwayTeamSelection, gbco.gridx(1)); panel.add(runButton, gbco.gridy(3).anchor(GridBagConstraints.CENTER)); + panel.add(results, gbco.gridy(4).anchor(GridBagConstraints.CENTER)); + this.getContentPane().add(panel); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); @@ -73,23 +85,34 @@ public GameScreenView(String title) { */ @Override public void actionPerformed(ActionEvent e) { - JComboBox cbSelected = (JComboBox)e.getSource(); - cbSelected.getModel(); - int selectedIndex = cbSelected.getSelectedIndex(); - if(cbSelected.getName().equalsIgnoreCase("Home")){ - // reset list for away team, minus the team selected for home. - AwayTeamsList.clear(); - AwayTeamsList.add(0, "Detroit Red Wings"); - AwayTeamsList.add(1, "Chicago Black Hawks"); - AwayTeamsList.add(2, "New York Rangers"); - AwayTeamsList.remove(selectedIndex); - }else if(cbSelected.getName().equalsIgnoreCase("Away")) { - // reset list for home team, minus the team selected for away. - HomeTeamsList.clear(); - HomeTeamsList.add(0, "Detroit Red Wings"); - HomeTeamsList.add(1, "Chicago Black Hawks"); - HomeTeamsList.add(2, "New York Rangers"); - HomeTeamsList.remove(selectedIndex); + Class action = e.getSource().getClass(); + if(action.isInstance(runButton)) { + runButtonClicked(e); + return; + }else { + JComboBox cbSelected = (JComboBox)e.getSource(); // TODO: figure out how to execute this more safely. + cbSelected.getModel(); + int selectedIndex = cbSelected.getSelectedIndex(); + if(cbSelected.getName().equalsIgnoreCase("Home")){ + // reset list for away team, minus the team selected for home. + AwayTeamsList.clear(); + AwayTeamsList.add(0, "Detroit Red Wings"); + AwayTeamsList.add(1, "Chicago Black Hawks"); + AwayTeamsList.add(2, "New York Rangers"); + AwayTeamsList.remove(selectedIndex); + }else if(cbSelected.getName().equalsIgnoreCase("Away")) { + // reset list for home team, minus the team selected for away. + HomeTeamsList.clear(); + HomeTeamsList.add(0, "Detroit Red Wings"); + HomeTeamsList.add(1, "Chicago Black Hawks"); + HomeTeamsList.add(2, "New York Rangers"); + HomeTeamsList.remove(selectedIndex); + } } } + + public void runButtonClicked(ActionEvent e) { + //add view of winner. + results.setText("you're the winner!"); + } } diff --git a/src/view/HockeyViewTextArea.java b/src/main/java/view/HockeyViewTextArea.java similarity index 96% rename from src/view/HockeyViewTextArea.java rename to src/main/java/view/HockeyViewTextArea.java index e1e906d..03b09db 100644 --- a/src/view/HockeyViewTextArea.java +++ b/src/main/java/view/HockeyViewTextArea.java @@ -1,7 +1,7 @@ /** * */ -package view; +package main.java.view; import java.awt.Color; diff --git a/src/view/TeamBuildingView.java b/src/main/java/view/TeamBuildingView.java similarity index 97% rename from src/view/TeamBuildingView.java rename to src/main/java/view/TeamBuildingView.java index bb5052b..1f8a1d4 100644 --- a/src/view/TeamBuildingView.java +++ b/src/main/java/view/TeamBuildingView.java @@ -1,4 +1,4 @@ -package view; +package main.java.view; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -7,7 +7,7 @@ import javax.swing.JButton; import javax.swing.JFrame; -import util.GridBagConstraintsObject; +import main.java.util.GridBagConstraintsObject; import javax.swing.JPanel; import javax.swing.JLabel; diff --git a/src/test/CreateTeamTest.java b/src/test/java/main/CreateTeamTest.java similarity index 95% rename from src/test/CreateTeamTest.java rename to src/test/java/main/CreateTeamTest.java index 4cc9c37..8d81315 100644 --- a/src/test/CreateTeamTest.java +++ b/src/test/java/main/CreateTeamTest.java @@ -11,9 +11,7 @@ * @version 31 March 2023 * @author Bryan Culver */ -package test; - -import static org.junit.jupiter.api.Assertions.*; +package test.java.main; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; diff --git a/src/test/GridBagConstraintsObjectTest.java b/src/test/java/util/GridBagConstraintsObjectTest.java similarity index 98% rename from src/test/GridBagConstraintsObjectTest.java rename to src/test/java/util/GridBagConstraintsObjectTest.java index 6f6be4a..135fc4d 100644 --- a/src/test/GridBagConstraintsObjectTest.java +++ b/src/test/java/util/GridBagConstraintsObjectTest.java @@ -1,7 +1,7 @@ /** * */ -package test; +package test.java.util; import static org.junit.jupiter.api.Assertions.*; @@ -14,7 +14,7 @@ import java.awt.GridBagConstraints; import java.awt.Insets; -import util.GridBagConstraintsObject; +import main.java.util.GridBagConstraintsObject; /** Test Class for the util.GridBag From f3bb6dd3f1909c80e540fb15c55cd338ada31afb Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Tue, 21 Nov 2023 08:02:34 -0500 Subject: [PATCH 21/45] implemented multi-window functionality Signed-off-by: Bryan Culver --- src/main/java/launch/Main.java | 1 - src/main/java/view/CreateTeamView.java | 85 ++++++++++++++++++++++++ src/main/java/view/GameScreenView.java | 38 ++++++++--- src/main/java/view/TeamBuildingView.java | 68 ------------------- 4 files changed, 112 insertions(+), 80 deletions(-) create mode 100644 src/main/java/view/CreateTeamView.java delete mode 100644 src/main/java/view/TeamBuildingView.java diff --git a/src/main/java/launch/Main.java b/src/main/java/launch/Main.java index 29959db..5688d6b 100644 --- a/src/main/java/launch/Main.java +++ b/src/main/java/launch/Main.java @@ -23,7 +23,6 @@ public static void main(String[] args) { public static void run() { GameScreenView view = new GameScreenView("The Fun Hockey App"); - view.setVisible(true); } } \ No newline at end of file diff --git a/src/main/java/view/CreateTeamView.java b/src/main/java/view/CreateTeamView.java new file mode 100644 index 0000000..259b782 --- /dev/null +++ b/src/main/java/view/CreateTeamView.java @@ -0,0 +1,85 @@ +package main.java.view; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; + +import main.java.util.GridBagConstraintsObject; + +import javax.swing.JTextArea; +import javax.swing.JPanel; +import javax.swing.JLabel; + +public class CreateTeamView{ + /** + * + */ + private JFrame createTeamFrame = new JFrame("Create a New Team"); + private JPanel panel; + + public CreateTeamView(String title) { + createTeamFrame.setTitle(title); + + GridBagLayout gbl = new GridBagLayout(); + panel = new JPanel(gbl); + + JLabel teamNameLabel = new JLabel("Team Name"); + JButton saveButton = new JButton("Save"); + JButton cancelButton = new JButton("Cancel"); + //int cupWins = 0; // TODO implement a get method for this. + //int standingLastYear = 12; // TODO implement a get method for this. + + // Implemented a HockeyViewTextArea class to avoid repeating changes to the JTextAreas. + //HockeyViewTextArea cupWinsTA = new HockeyViewTextArea(Integer.toString(cupWins),createTeamFrame.getBackground()); + //HockeyViewTextArea standingTA = new HockeyViewTextArea(Integer.toString(standingLastYear), createTeamFrame.getBackground()); + //HockeyViewTextArea userNameTA = new HockeyViewTextArea("username", createTeamFrame.getBackground()); + JTextArea locationTA = new JTextArea("City/State"); + JTextArea teamNameTA = new JTextArea("Team Name"); + + GridBagConstraintsObject gbco = new GridBagConstraintsObject(); + gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); + + //panel.add(new JLabel("Owner's Name"),gbco.gridx(0).gridy(0)); + panel.add(new JLabel("Team's Location"), gbco.gridy(1).gridx(0)); + panel.add(teamNameLabel, gbco.gridy(2).gridx(0)); + //panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3).gridx(0)); + //panel.add(new JLabel("Last Year's standing"), gbco.gridy(4).gridx(0)); + + //panel.add(userNameTA,gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL).weightx(0.6)); + panel.add(locationTA, gbco.gridx(1).gridy(1)); + panel.add(teamNameTA, gbco.gridx(1).gridy(2)); + //panel.add(cupWinsTA, gbco.gridx(1).gridy(3)); + //panel.add(standingTA, gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); + + panel.add(cancelButton, gbco.gridx(0).gridy(5).anchor(GridBagConstraints.LAST_LINE_START).fill(0)); + panel.add(saveButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END).weightx(0)); + + saveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + //Check data submitted + //Save team information submitted + GameScreenView welcomeView = new GameScreenView("Hockey App"); + createTeamFrame.dispose(); + } + }); + + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GameScreenView welcomeView = new GameScreenView("Hockey App"); + createTeamFrame.dispose(); + } + }); + + createTeamFrame.getContentPane().add(panel); + createTeamFrame.setLocationRelativeTo(null); + createTeamFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + createTeamFrame.pack(); + createTeamFrame.setVisible(true); + } +} \ No newline at end of file diff --git a/src/main/java/view/GameScreenView.java b/src/main/java/view/GameScreenView.java index 0d4c7ee..fc8c681 100644 --- a/src/main/java/view/GameScreenView.java +++ b/src/main/java/view/GameScreenView.java @@ -20,29 +20,40 @@ * @author Bryan Culver * @version 7 October 2023 */ -public class GameScreenView extends JFrame implements ActionListener{ +public class GameScreenView implements ActionListener{ /** * */ - private static final long serialVersionUID = 1L; // required for serializable class. + JFrame welcomeView = new JFrame("Hockey App"); Vector AwayTeamsList; Vector HomeTeamsList; JButton runButton; - HockeyViewTextArea results= new HockeyViewTextArea("The winner is...", this.getBackground()); + HockeyViewTextArea results= new HockeyViewTextArea("The winner is...", welcomeView.getBackground()); //private JPanel jPanel; public GameScreenView(String title) { - super(title); + welcomeView.setTitle(title); GridBagLayout gbl = new GridBagLayout(); JPanel panel = new JPanel(gbl); runButton = new JButton("Run Game Prediction"); + JButton deleteButton = new JButton("Delete Team"); + JButton editButton = new JButton("Edit Team"); + JButton newButton = new JButton("New Team"); + + newButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + CreateTeamView newTeamView = new CreateTeamView("Create a New Team"); + welcomeView.dispose(); + } + }); runButton.addActionListener(this); // TODO: the game can be implemented here. //runButton.addActionListener(StartGame); - HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", this.getBackground()); - HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", this.getBackground()); + HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", welcomeView.getBackground()); + HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", welcomeView.getBackground()); HomeTeamsList = new Vector<>(); HomeTeamsList.add("Detroit Red Wings"); @@ -69,19 +80,24 @@ public GameScreenView(String title) { panel.add(HomeTeamSelection, gbco.gridx(0).gridy(1)); panel.add(AwayTeamSelection, gbco.gridx(1)); panel.add(runButton, gbco.gridy(3).anchor(GridBagConstraints.CENTER)); + panel.add(newButton, gbco.gridx(0).anchor(GridBagConstraints.WEST)); + panel.add(editButton, gbco.gridy(4)); + panel.add(deleteButton, gbco.gridy(5)); - panel.add(results, gbco.gridy(4).anchor(GridBagConstraints.CENTER)); + panel.add(results, gbco.gridy(6).anchor(GridBagConstraints.CENTER)); - this.getContentPane().add(panel); - this.setLocationRelativeTo(null); - this.setDefaultCloseOperation(EXIT_ON_CLOSE); + welcomeView.getContentPane().add(panel); + welcomeView.setLocationRelativeTo(null); + welcomeView.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.pack(); + welcomeView.pack(); + welcomeView.setVisible(true); } /** * Action listener will remove the selected team from the other combo box + * This may need to be implemented within the above class on each combo box/spinner. */ @Override public void actionPerformed(ActionEvent e) { diff --git a/src/main/java/view/TeamBuildingView.java b/src/main/java/view/TeamBuildingView.java deleted file mode 100644 index 1f8a1d4..0000000 --- a/src/main/java/view/TeamBuildingView.java +++ /dev/null @@ -1,68 +0,0 @@ -package main.java.view; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JFrame; - -import main.java.util.GridBagConstraintsObject; - -import javax.swing.JPanel; -import javax.swing.JLabel; - -public class TeamBuildingView extends JFrame{ - /** - * - */ - private static final long serialVersionUID = 1L; - private JPanel panel; - private ActionListener saveListener; // TODO Implement listener class in main package. - - public TeamBuildingView(String title) { - super(title); - - GridBagLayout gbl = new GridBagLayout(); - panel = new JPanel(gbl); - - JLabel teamTitleLabel = new JLabel("Team Title"); - JButton saveButton = new JButton("Save"); - JButton editButton = new JButton("Edit"); - int cupWins = 0; // TODO implement a get method for this. - int standingLastYear = 12; // TODO implement a get method for this. - - // Implemented a HockeyViewTextArea class to avoid repeating changes to the JTextAreas. - HockeyViewTextArea cupWinsTA = new HockeyViewTextArea(Integer.toString(cupWins),this.getBackground()); - HockeyViewTextArea standingTA = new HockeyViewTextArea(Integer.toString(standingLastYear), this.getBackground()); - HockeyViewTextArea userNameTA = new HockeyViewTextArea("username", this.getBackground()); - HockeyViewTextArea locationTA = new HockeyViewTextArea("City, State", this.getBackground()); - HockeyViewTextArea teamNameTA = new HockeyViewTextArea("Team Name", this.getBackground()); - - GridBagConstraintsObject gbco = new GridBagConstraintsObject(); - gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); - - panel.add(new JLabel("Owner's Name"),gbco.gridx(0).gridy(0)); - panel.add(new JLabel("Team's Location"), gbco.gridy(1).gridx(0)); - panel.add(teamTitleLabel, gbco.gridy(2).gridx(0)); - panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3).gridx(0)); - panel.add(new JLabel("Last Year's standing"), gbco.gridy(4).gridx(0)); - - panel.add(userNameTA,gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL).weightx(0.6)); - panel.add(locationTA, gbco.gridx(1).gridy(1)); - panel.add(teamNameTA, gbco.gridx(1).gridy(2)); - panel.add(cupWinsTA, gbco.gridx(1).gridy(3)); - panel.add(standingTA, gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); - - panel.add(editButton, gbco.gridx(0).gridy(5).anchor(GridBagConstraints.LAST_LINE_START).fill(0)); - panel.add(saveButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END).weightx(0)); - - saveButton.addActionListener(saveListener); // TODO Implement listener class in main package - - this.getContentPane().add(panel); - this.setLocationRelativeTo(null); - this.setDefaultCloseOperation(EXIT_ON_CLOSE); - - this.pack(); - } -} \ No newline at end of file From dfc5be416a579898c800512b770e3c815d215837 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Tue, 21 Nov 2023 16:55:50 -0500 Subject: [PATCH 22/45] added model package and Game and Team classes in order to predict game Signed-off-by: Bryan Culver --- src/main/java/model/Game.java | 60 +++++++++++++++++++++++++++++++++++ src/main/java/model/Team.java | 26 +++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/main/java/model/Game.java create mode 100644 src/main/java/model/Team.java diff --git a/src/main/java/model/Game.java b/src/main/java/model/Game.java new file mode 100644 index 0000000..5885b1c --- /dev/null +++ b/src/main/java/model/Game.java @@ -0,0 +1,60 @@ +/** + * + */ +package main.java.model; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author "Bryan Culver" + * + */ +public class Game { + private Team homeTeam; + private Team awayTeam; + private int scoreAway = 0; + private int scoreHome = 0; + //private boolean overtime; + private final int RANDOM_MAX = 100; + private final int RANDOM_MIN = 0; + + public Game(Team homeTeam, Team awayTeam) { + this.awayTeam = awayTeam; + this.homeTeam = homeTeam; + play(); + } + + public Team getHomeTeam() { + return homeTeam; + } + + public Team getAwayTeam() { + return awayTeam; + } + + public int getScoreAway() { + return scoreAway; + } + + public int getScoreHome() { + return scoreHome; + } + + private void play() { + int randomNum = ThreadLocalRandom.current().nextInt(RANDOM_MIN, RANDOM_MAX +1); + for (int period=1;period<=3;period++) { + if(randomNum>60) { + scoreAway++; + }else { + scoreHome++; + } + } + } + + public String toString() { + String result = ""; + result = awayTeam.getLocation()+" "+awayTeam.getName()+" at "+homeTeam.getLocation()+" "+homeTeam.getName()+": "+scoreAway+" - "+scoreHome; + return result; + } + +} diff --git a/src/main/java/model/Team.java b/src/main/java/model/Team.java new file mode 100644 index 0000000..b41bf85 --- /dev/null +++ b/src/main/java/model/Team.java @@ -0,0 +1,26 @@ +/** + * + */ +package main.java.model; + +/** + * @author "Bryan Culver" + * + */ +public class Team { + String location = ""; + String name = ""; + + public Team(String location, String name) { + this.location = location; + this.name = name; + } + + public String getName() { + return name; + } + + public String getLocation() { + return location; + } +} From ef17de47a5ef1f0866369b45756be6098f8173d7 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Wed, 22 Nov 2023 21:27:37 -0500 Subject: [PATCH 23/45] Application simulates a game. everything is crude, but we have an initial structure Signed-off-by: Bryan Culver --- src/main/java/launch/Main.java | 1 + src/main/java/model/Game.java | 16 ++-- src/main/java/view/CreateTeamView.java | 2 + src/main/java/view/GameScreenView.java | 111 +++++++++++-------------- 4 files changed, 59 insertions(+), 71 deletions(-) diff --git a/src/main/java/launch/Main.java b/src/main/java/launch/Main.java index 5688d6b..295c325 100644 --- a/src/main/java/launch/Main.java +++ b/src/main/java/launch/Main.java @@ -22,6 +22,7 @@ public static void main(String[] args) { } public static void run() { + @SuppressWarnings("unused") GameScreenView view = new GameScreenView("The Fun Hockey App"); } diff --git a/src/main/java/model/Game.java b/src/main/java/model/Game.java index 5885b1c..e83b498 100644 --- a/src/main/java/model/Game.java +++ b/src/main/java/model/Game.java @@ -10,25 +10,25 @@ * */ public class Game { - private Team homeTeam; - private Team awayTeam; + private String homeTeam; + private String awayTeam; private int scoreAway = 0; private int scoreHome = 0; //private boolean overtime; private final int RANDOM_MAX = 100; private final int RANDOM_MIN = 0; - public Game(Team homeTeam, Team awayTeam) { + public Game(String homeTeam, String awayTeam) { this.awayTeam = awayTeam; this.homeTeam = homeTeam; play(); } - public Team getHomeTeam() { + public String getHomeTeam() { return homeTeam; } - public Team getAwayTeam() { + public String getAwayTeam() { return awayTeam; } @@ -41,8 +41,8 @@ public int getScoreHome() { } private void play() { - int randomNum = ThreadLocalRandom.current().nextInt(RANDOM_MIN, RANDOM_MAX +1); for (int period=1;period<=3;period++) { + int randomNum = ThreadLocalRandom.current().nextInt(RANDOM_MIN, RANDOM_MAX +1); if(randomNum>60) { scoreAway++; }else { @@ -51,10 +51,10 @@ private void play() { } } - public String toString() { + /*public String toString() { String result = ""; result = awayTeam.getLocation()+" "+awayTeam.getName()+" at "+homeTeam.getLocation()+" "+homeTeam.getName()+": "+scoreAway+" - "+scoreHome; return result; - } + }*/ } diff --git a/src/main/java/view/CreateTeamView.java b/src/main/java/view/CreateTeamView.java index 259b782..b90f6f1 100644 --- a/src/main/java/view/CreateTeamView.java +++ b/src/main/java/view/CreateTeamView.java @@ -62,6 +62,7 @@ public CreateTeamView(String title) { public void actionPerformed(ActionEvent e) { //Check data submitted //Save team information submitted + @SuppressWarnings("unused") GameScreenView welcomeView = new GameScreenView("Hockey App"); createTeamFrame.dispose(); } @@ -70,6 +71,7 @@ public void actionPerformed(ActionEvent e) { cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unused") GameScreenView welcomeView = new GameScreenView("Hockey App"); createTeamFrame.dispose(); } diff --git a/src/main/java/view/GameScreenView.java b/src/main/java/view/GameScreenView.java index fc8c681..3ba478d 100644 --- a/src/main/java/view/GameScreenView.java +++ b/src/main/java/view/GameScreenView.java @@ -7,30 +7,35 @@ import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Vector; // TODO: transition from Vector to ArrayList - bottleneck: JComboBox. +import java.util.ArrayList; // TODO: transition from Vector to ArrayList - bottleneck: JComboBox. import javax.swing.JFrame; import javax.swing.JPanel; -import javax.swing.JComboBox; +import javax.swing.JSpinner; +import javax.swing.SpinnerListModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.JButton; import main.java.util.GridBagConstraintsObject; +import main.java.model.Game; /** * @author Bryan Culver * @version 7 October 2023 */ -public class GameScreenView implements ActionListener{ +public class GameScreenView{ /** * */ JFrame welcomeView = new JFrame("Hockey App"); - Vector AwayTeamsList; - Vector HomeTeamsList; + ArrayList awayTeamsList; + ArrayList homeTeamsList; JButton runButton; HockeyViewTextArea results= new HockeyViewTextArea("The winner is...", welcomeView.getBackground()); - //private JPanel jPanel; + JSpinner homeTeamSelection; + JSpinner awayTeamSelection; public GameScreenView(String title) { welcomeView.setTitle(title); GridBagLayout gbl = new GridBagLayout(); @@ -43,42 +48,59 @@ public GameScreenView(String title) { newButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + @SuppressWarnings("unused") CreateTeamView newTeamView = new CreateTeamView("Create a New Team"); welcomeView.dispose(); } }); - runButton.addActionListener(this); - // TODO: the game can be implemented here. - //runButton.addActionListener(StartGame); + runButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String matchupResults = ""; + Game matchup = new Game(homeTeamSelection.getValue().toString(), awayTeamSelection.getValue().toString()); + matchupResults = matchup.getAwayTeam()+" at "+matchup.getHomeTeam()+": "+matchup.getScoreAway()+" - "+matchup.getScoreHome(); + results.setText(matchupResults); + } + }); HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", welcomeView.getBackground()); HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", welcomeView.getBackground()); - HomeTeamsList = new Vector<>(); - HomeTeamsList.add("Detroit Red Wings"); - HomeTeamsList.add("Chicago Black Hawks"); - HomeTeamsList.add("New York Rangers"); + homeTeamsList = new ArrayList<>(); + homeTeamsList.add("Detroit Red Wings"); + homeTeamsList.add("Chicago Black Hawks"); + homeTeamsList.add("New York Rangers"); + + awayTeamsList = new ArrayList<>(); + awayTeamsList.add("Detroit Red Wings"); + awayTeamsList.add("Chicago Black Hawks"); + awayTeamsList.add("New York Rangers"); - AwayTeamsList = new Vector<>(); - AwayTeamsList.add("Detroit Red Wings"); - AwayTeamsList.add("Chicago Black Hawks"); - AwayTeamsList.add("New York Rangers"); - - JComboBox HomeTeamSelection = new JComboBox(HomeTeamsList); - HomeTeamSelection.setName("Home"); - JComboBox AwayTeamSelection = new JComboBox(AwayTeamsList); - AwayTeamSelection.setName("Away"); + SpinnerListModel homeSpinnerModel = new SpinnerListModel(homeTeamsList); + homeTeamSelection = new JSpinner(homeSpinnerModel); + homeTeamSelection.setName("Home"); + SpinnerListModel awaySpinnerModel = new SpinnerListModel(awayTeamsList); + awayTeamSelection = new JSpinner(awaySpinnerModel); + awayTeamSelection.setName("Away"); - HomeTeamSelection.addActionListener(this); - AwayTeamSelection.addActionListener(this); + homeTeamSelection.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + // TODO Auto-generated method stub + } + }); + awayTeamSelection.addChangeListener(new ChangeListener(){ + public void stateChanged(ChangeEvent e) { + // away team actions. + } + }); GridBagConstraintsObject gbco = new GridBagConstraintsObject(); gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); panel.add(HomeTeamLabel, gbco.gridx(0).gridy(0)); panel.add(AwayTeamLabel, gbco.gridx(1)); - panel.add(HomeTeamSelection, gbco.gridx(0).gridy(1)); - panel.add(AwayTeamSelection, gbco.gridx(1)); + panel.add(homeTeamSelection, gbco.gridx(0).gridy(1)); + panel.add(awayTeamSelection, gbco.gridx(1)); panel.add(runButton, gbco.gridy(3).anchor(GridBagConstraints.CENTER)); panel.add(newButton, gbco.gridx(0).anchor(GridBagConstraints.WEST)); panel.add(editButton, gbco.gridy(4)); @@ -94,41 +116,4 @@ public void actionPerformed(ActionEvent e) { welcomeView.setVisible(true); } - - /** - * Action listener will remove the selected team from the other combo box - * This may need to be implemented within the above class on each combo box/spinner. - */ - @Override - public void actionPerformed(ActionEvent e) { - Class action = e.getSource().getClass(); - if(action.isInstance(runButton)) { - runButtonClicked(e); - return; - }else { - JComboBox cbSelected = (JComboBox)e.getSource(); // TODO: figure out how to execute this more safely. - cbSelected.getModel(); - int selectedIndex = cbSelected.getSelectedIndex(); - if(cbSelected.getName().equalsIgnoreCase("Home")){ - // reset list for away team, minus the team selected for home. - AwayTeamsList.clear(); - AwayTeamsList.add(0, "Detroit Red Wings"); - AwayTeamsList.add(1, "Chicago Black Hawks"); - AwayTeamsList.add(2, "New York Rangers"); - AwayTeamsList.remove(selectedIndex); - }else if(cbSelected.getName().equalsIgnoreCase("Away")) { - // reset list for home team, minus the team selected for away. - HomeTeamsList.clear(); - HomeTeamsList.add(0, "Detroit Red Wings"); - HomeTeamsList.add(1, "Chicago Black Hawks"); - HomeTeamsList.add(2, "New York Rangers"); - HomeTeamsList.remove(selectedIndex); - } - } - } - - public void runButtonClicked(ActionEvent e) { - //add view of winner. - results.setText("you're the winner!"); - } } From 9950634a6f2ac763e824683868dacafcab871fca Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Wed, 22 Nov 2023 21:40:59 -0500 Subject: [PATCH 24/45] made updates to .gitignore --- .gitignore | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e7ce5b2..e5a66f6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,9 @@ ### Gradle ### .gradle +.gradle/ /build/ +.metadata # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -30,8 +32,4 @@ hs_err_pid* .project .settings/ .classpath -/bin/ - -# local Gradle files -.gradle/ -.metadata/ +/bin/ \ No newline at end of file From 18cef18658f12200bb22f26d6e31052905b546e3 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Wed, 22 Nov 2023 21:40:59 -0500 Subject: [PATCH 25/45] made updates to .gitignore Signed-off-by: Bryan Culver --- .gitignore | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e7ce5b2..e5a66f6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,9 @@ ### Gradle ### .gradle +.gradle/ /build/ +.metadata # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -30,8 +32,4 @@ hs_err_pid* .project .settings/ .classpath -/bin/ - -# local Gradle files -.gradle/ -.metadata/ +/bin/ \ No newline at end of file From 84180b48219eff33a7e8248f53bf10e8bf48ca77 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Fri, 22 Sep 2023 23:31:41 -0400 Subject: [PATCH 26/45] Added initial file to test the save function, and added a Team object, to provide something to save --- src/main/Team.java | 65 ++++++++++++++++++++++++++++++++++++++ src/test/SaveTeamTest.java | 24 ++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/main/Team.java create mode 100644 src/test/SaveTeamTest.java diff --git a/src/main/Team.java b/src/main/Team.java new file mode 100644 index 0000000..bddd714 --- /dev/null +++ b/src/main/Team.java @@ -0,0 +1,65 @@ +/** + * + */ +package main; + +/** + * @author Bryan Culver + * + */ +public class Team { + + private String teamName; + private String teamLocation; + + /** + * Constructor that builds an empty team + */ + public Team(){ + this.teamName = " "; + this.teamLocation = " "; + } + + public Team(String location, String name) { + this.teamName = name; + this.teamLocation = location; + } + + /** + * Method that writes data in the form of a JSON to a file + */ + public boolean saveTeam() { + //code to save the team's info + return true; + } + + /** + * Method to load the team from specified location. + */ + public boolean loadTeam() { + // code to load team info from file to memory. + return true; + } + + public String toString() { + return (teamLocation + " " + teamName); + } + + public boolean setTeamName(String newName) { + teamName = newName; + return true; + } + + public boolean setTeamLocation(String newLocation) { + teamLocation = newLocation; + return true; + } + + public String getTeamName() { + return teamName; + } + + public String getTeamLocation() { + return teamLocation; + } +} diff --git a/src/test/SaveTeamTest.java b/src/test/SaveTeamTest.java new file mode 100644 index 0000000..99fe84f --- /dev/null +++ b/src/test/SaveTeamTest.java @@ -0,0 +1,24 @@ +/** + * + */ +package test; + +import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; + +/** + * @author Bryan Culver + * + */ +class SaveTeamTest { + + @BeforeAll + void TeamSetup() { + + } + + @Test + void TeamSaveTest(){ + + } +} From b1f67f68a39660f372a5ca6bc96e56dd17c7dfc9 Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 25 Sep 2023 21:10:41 -0400 Subject: [PATCH 27/45] committing the rest of the files changed --- build.gradle | 6 ++++-- src/test/SaveTeamTest.java | 24 ------------------------ src/test/java/main/CreateTeamTest.java | 23 ++++++++++++++++++----- 3 files changed, 22 insertions(+), 31 deletions(-) delete mode 100644 src/test/SaveTeamTest.java diff --git a/build.gradle b/build.gradle index e2145c1..8a10513 100644 --- a/build.gradle +++ b/build.gradle @@ -1,2 +1,4 @@ -apply plugin: 'java' -apply plugin: 'eclipse' \ No newline at end of file +plugins{ + id 'java' + id 'eclipse' +} \ No newline at end of file diff --git a/src/test/SaveTeamTest.java b/src/test/SaveTeamTest.java deleted file mode 100644 index 99fe84f..0000000 --- a/src/test/SaveTeamTest.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * - */ -package test; - -import org.junit.Test; -import org.junit.jupiter.api.BeforeAll; - -/** - * @author Bryan Culver - * - */ -class SaveTeamTest { - - @BeforeAll - void TeamSetup() { - - } - - @Test - void TeamSaveTest(){ - - } -} diff --git a/src/test/java/main/CreateTeamTest.java b/src/test/java/main/CreateTeamTest.java index 8d81315..c31b9e9 100644 --- a/src/test/java/main/CreateTeamTest.java +++ b/src/test/java/main/CreateTeamTest.java @@ -19,20 +19,26 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import main.Team; + /** * @author "Bryan Culver" * */ -class CreateTeamTest { - +class TeamTest { + Team teamTestA; + Team teamTestB; /** * @throws java.lang.Exception */ @BeforeAll static void setUpBeforeClass() throws Exception { - //view = new TeamBuildingView("Test Build"); + Team teamTestA = new Team(); + assertEquals(" ", teamTestA.toString()); + Team teamTestB = new Team("Detroit", "Red_Wings"); + assertEquals("Detroit Red_Wings", teamTestB.toString()); } /** @@ -58,8 +64,15 @@ void tearDown() throws Exception { } @Test - void test() { - fail("Not yet implemented"); + void testTeamCreation() { + assertTrue(this.teamTestA!=null); + assertEquals("Detroit", teamTestB.getTeamLocation()); + assertEquals("Red_Wings", teamTestB.getTeamName()); + + teamTestA.setTeamLocation("Buffalo"); + teamTestB.setTeamName("Sabers"); + assertEquals("Buffalo", teamTestA.getTeamLocation()); + assertEquals("Sabers", teamTestA.getTeamName()); } } From 0d56a6e58210aa7bca937af3c4cba5bd0b1139fb Mon Sep 17 00:00:00 2001 From: BoringBryan Date: Mon, 2 Oct 2023 21:11:06 -0400 Subject: [PATCH 28/45] continuing to do work on the gradle file. --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 8a10513..7721093 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,10 @@ plugins{ id 'java' id 'eclipse' + id 'jacoco' +} + +test { + useJUnitPlatform() + finalizedBy jacocoTestReport } \ No newline at end of file From 2b972535289fffb0bebf0cc99d5e774fa9358412 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 1 Mar 2024 15:15:50 -0500 Subject: [PATCH 29/45] These are some random updates and improvements --- src/main/Main.java | 28 --- src/main/Team.java | 65 ------- src/main/java/model/Game.java | 22 ++- src/main/java/model/Team.java | 9 + src/main/java/view/GameScreenView.java | 27 +-- src/test/java/main/CreateTeamTest.java | 78 -------- src/test/java/model/GameTest.java | 31 +++ src/test/java/model/TeamTest.java | 48 +++++ .../util/GridBagConstraintsObjectTest.java | 177 ------------------ src/view/HockeyViewTextArea.java | 35 ---- src/view/TeamBuildingView.java | 68 ------- 11 files changed, 118 insertions(+), 470 deletions(-) delete mode 100644 src/main/Main.java delete mode 100644 src/main/Team.java delete mode 100644 src/test/java/main/CreateTeamTest.java create mode 100644 src/test/java/model/GameTest.java create mode 100644 src/test/java/model/TeamTest.java delete mode 100644 src/test/java/util/GridBagConstraintsObjectTest.java delete mode 100644 src/view/HockeyViewTextArea.java delete mode 100644 src/view/TeamBuildingView.java diff --git a/src/main/Main.java b/src/main/Main.java deleted file mode 100644 index e1ccb6e..0000000 --- a/src/main/Main.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This is the Main view for the Team building Interface window. - */ -package main; - -import view.TeamBuildingView; - -/** - * - * @author "Bryan Culver" - * - */ -public class Main { - - /** - * The main method that runs the app to open the first view. - * @param args - */ - public static void main(String[] args) { - run(); - } - - public static void run() { - TeamBuildingView view = new TeamBuildingView("The Fun Hockey App"); - view.setVisible(true); - } - -} \ No newline at end of file diff --git a/src/main/Team.java b/src/main/Team.java deleted file mode 100644 index bddd714..0000000 --- a/src/main/Team.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * - */ -package main; - -/** - * @author Bryan Culver - * - */ -public class Team { - - private String teamName; - private String teamLocation; - - /** - * Constructor that builds an empty team - */ - public Team(){ - this.teamName = " "; - this.teamLocation = " "; - } - - public Team(String location, String name) { - this.teamName = name; - this.teamLocation = location; - } - - /** - * Method that writes data in the form of a JSON to a file - */ - public boolean saveTeam() { - //code to save the team's info - return true; - } - - /** - * Method to load the team from specified location. - */ - public boolean loadTeam() { - // code to load team info from file to memory. - return true; - } - - public String toString() { - return (teamLocation + " " + teamName); - } - - public boolean setTeamName(String newName) { - teamName = newName; - return true; - } - - public boolean setTeamLocation(String newLocation) { - teamLocation = newLocation; - return true; - } - - public String getTeamName() { - return teamName; - } - - public String getTeamLocation() { - return teamLocation; - } -} diff --git a/src/main/java/model/Game.java b/src/main/java/model/Game.java index e83b498..34f2a3b 100644 --- a/src/main/java/model/Game.java +++ b/src/main/java/model/Game.java @@ -5,31 +5,41 @@ import java.util.concurrent.ThreadLocalRandom; -/** +/**The Game class creates and runs a Hockey game, generating all stats that come from it. * @author "Bryan Culver" * */ public class Game { - private String homeTeam; - private String awayTeam; + private Team homeTeam; + private Team awayTeam; private int scoreAway = 0; private int scoreHome = 0; //private boolean overtime; private final int RANDOM_MAX = 100; private final int RANDOM_MIN = 0; - public Game(String homeTeam, String awayTeam) { + /**Game will take two teams, play a game between them, and generate stats from the game. + * Stats are available through getters. + * + * @param homeTeam + * @param awayTeam + */ + public Game(Team awayTeam, Team homeTeam) { this.awayTeam = awayTeam; this.homeTeam = homeTeam; play(); } + /**This getter provides a string of the team's location and name. + * + * @return String + */ public String getHomeTeam() { - return homeTeam; + return homeTeam.toString(); } public String getAwayTeam() { - return awayTeam; + return awayTeam.toString(); } public int getScoreAway() { diff --git a/src/main/java/model/Team.java b/src/main/java/model/Team.java index b41bf85..f437752 100644 --- a/src/main/java/model/Team.java +++ b/src/main/java/model/Team.java @@ -11,6 +11,11 @@ public class Team { String location = ""; String name = ""; + /** + * This class takes two strings and creates a simple team class. + * @param location String + * @param name String + */ public Team(String location, String name) { this.location = location; this.name = name; @@ -23,4 +28,8 @@ public String getName() { public String getLocation() { return location; } + + public String toString() { + return location + " " + name; + } } diff --git a/src/main/java/view/GameScreenView.java b/src/main/java/view/GameScreenView.java index 3ba478d..d6bb91b 100644 --- a/src/main/java/view/GameScreenView.java +++ b/src/main/java/view/GameScreenView.java @@ -4,6 +4,7 @@ package main.java.view; import java.awt.GridBagConstraints; + import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -19,6 +20,7 @@ import main.java.util.GridBagConstraintsObject; import main.java.model.Game; +import main.java.model.Team; /** * @author Bryan Culver @@ -26,12 +28,9 @@ */ public class GameScreenView{ - /** - * - */ JFrame welcomeView = new JFrame("Hockey App"); - ArrayList awayTeamsList; - ArrayList homeTeamsList; + ArrayList awayTeamsList; + ArrayList homeTeamsList; JButton runButton; HockeyViewTextArea results= new HockeyViewTextArea("The winner is...", welcomeView.getBackground()); JSpinner homeTeamSelection; @@ -56,8 +55,10 @@ public void actionPerformed(ActionEvent e) { runButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Team homeSelect = (Team) homeTeamSelection.getValue(); + Team awaySelect = (Team) awayTeamSelection.getValue(); String matchupResults = ""; - Game matchup = new Game(homeTeamSelection.getValue().toString(), awayTeamSelection.getValue().toString()); + Game matchup = new Game(homeSelect, awaySelect); matchupResults = matchup.getAwayTeam()+" at "+matchup.getHomeTeam()+": "+matchup.getScoreAway()+" - "+matchup.getScoreHome(); results.setText(matchupResults); } @@ -66,15 +67,15 @@ public void actionPerformed(ActionEvent e) { HockeyViewTextArea HomeTeamLabel = new HockeyViewTextArea("Home Team", welcomeView.getBackground()); HockeyViewTextArea AwayTeamLabel = new HockeyViewTextArea("Away Team", welcomeView.getBackground()); - homeTeamsList = new ArrayList<>(); - homeTeamsList.add("Detroit Red Wings"); - homeTeamsList.add("Chicago Black Hawks"); - homeTeamsList.add("New York Rangers"); + homeTeamsList = new ArrayList(); + homeTeamsList.add(new Team("Detroit", "Red Wings")); + homeTeamsList.add(new Team("Chicago", "Black Hawks")); + homeTeamsList.add(new Team("New York", "Rangers")); awayTeamsList = new ArrayList<>(); - awayTeamsList.add("Detroit Red Wings"); - awayTeamsList.add("Chicago Black Hawks"); - awayTeamsList.add("New York Rangers"); + awayTeamsList.add(new Team("Detroit", "Red Wings")); + awayTeamsList.add(new Team("Chicago", "Black Hawks")); + awayTeamsList.add(new Team("New York", "Rangers")); SpinnerListModel homeSpinnerModel = new SpinnerListModel(homeTeamsList); homeTeamSelection = new JSpinner(homeSpinnerModel); diff --git a/src/test/java/main/CreateTeamTest.java b/src/test/java/main/CreateTeamTest.java deleted file mode 100644 index c31b9e9..0000000 --- a/src/test/java/main/CreateTeamTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/**First Testing class - * - * This class is an example of where the testing classes should be kept and how they should - * be maintained. - * - * This class will eventually be overwritten with the first actual test class once testing - * is required. UI elements will not be tested in this project and should be grouped with - * the "View" package maintaining minimal dependency between the model and controller and - * the "View" package. - * - * @version 31 March 2023 - * @author Bryan Culver - */ -package test.java.main; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import main.Team; - - -/** - * @author "Bryan Culver" - * - */ -class TeamTest { - Team teamTestA; - Team teamTestB; - - /** - * @throws java.lang.Exception - */ - @BeforeAll - static void setUpBeforeClass() throws Exception { - Team teamTestA = new Team(); - assertEquals(" ", teamTestA.toString()); - Team teamTestB = new Team("Detroit", "Red_Wings"); - assertEquals("Detroit Red_Wings", teamTestB.toString()); - } - - /** - * @throws java.lang.Exception - */ - @AfterAll - static void tearDownAfterClass() throws Exception { - - } - - /** - * @throws java.lang.Exception - */ - @BeforeEach - void setUp() throws Exception { - } - - /** - * @throws java.lang.Exception - */ - @AfterEach - void tearDown() throws Exception { - } - - @Test - void testTeamCreation() { - assertTrue(this.teamTestA!=null); - assertEquals("Detroit", teamTestB.getTeamLocation()); - assertEquals("Red_Wings", teamTestB.getTeamName()); - - teamTestA.setTeamLocation("Buffalo"); - teamTestB.setTeamName("Sabers"); - assertEquals("Buffalo", teamTestA.getTeamLocation()); - assertEquals("Sabers", teamTestA.getTeamName()); - } - -} diff --git a/src/test/java/model/GameTest.java b/src/test/java/model/GameTest.java new file mode 100644 index 0000000..532f6b8 --- /dev/null +++ b/src/test/java/model/GameTest.java @@ -0,0 +1,31 @@ +/** + * + */ +package test.java.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import main.java.model.Game; +import main.java.model.Team; + +/**Class to test the function of the Game class + * @author "Bryan Culver" + * @version 2024.02.23 + */ +public class GameTest { + + /** + * run a test on the game constructor and confirm that the total score is 3 + * (Based on current game logic.) + */ + @Test + public void constructGameTest() { + Team stubTeam1 = new Team("StubLocation","StubName"); + Team stubTeam2 = new Team("Stub2Location","Stub2Name"); + Game testGame1 = new Game(stubTeam1, stubTeam2); + assertEquals(3, testGame1.getScoreAway() + testGame1.getScoreHome(), "Total score is not equal to 3"); + assertEquals("StubLocation StubName", testGame1.getAwayTeam(),"Away team's name is wrong"); + assertEquals("Stub2Location Stub2Name", testGame1.getHomeTeam(),"Home team's name is wrong"); + } +} diff --git a/src/test/java/model/TeamTest.java b/src/test/java/model/TeamTest.java new file mode 100644 index 0000000..8b5f303 --- /dev/null +++ b/src/test/java/model/TeamTest.java @@ -0,0 +1,48 @@ +/**First Testing class + * + * This class is an example of where the testing classes should be kept and how they should + * be maintained. + * + * This class will eventually be overwritten with the first actual test class once testing + * is required. UI elements will not be tested in this project and should be grouped with + * the "View" package maintaining minimal dependency between the model and controller and + * the "View" package. + * + * @version 31 March 2023 + * @author Bryan Culver + */ +package test.java.model; + +import static org.junit.Assert.assertEquals; + +//import org.junit.jupiter.api.AfterAll; +//import org.junit.jupiter.api.AfterEach; +//import org.junit.jupiter.api.BeforeAll; +//import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.*; + +import main.java.model.*; + + +/**Testing the Team class + * @author "Bryan Culver" + * @version 2024.02.23 + */ +public class TeamTest { + Team teamTestA; + Team teamTestB; + + @Test + public void testTeamCreation() { + Team teamTestA = new Team("Chicago", "Black Hawks"); +// assert teamTestA.getLocation().equals("Chicago"); +// assert teamTestA.getName().equals("Black Hawks"); +// Team teamTestB = new Team("Detroit", "Red_Wings"); +// assert teamTestB.getLocation().equals("Detroit"); +// assert teamTestB.getName().equals("Red_Wings"); + assertEquals("","Chicago",teamTestA.getLocation()); + assertEquals("","Black Hawks",teamTestA.getName()); + // toString is tested in GameTest + } + +} diff --git a/src/test/java/util/GridBagConstraintsObjectTest.java b/src/test/java/util/GridBagConstraintsObjectTest.java deleted file mode 100644 index 135fc4d..0000000 --- a/src/test/java/util/GridBagConstraintsObjectTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * - */ -package test.java.util; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.awt.GridBagConstraints; -import java.awt.Insets; - -import main.java.util.GridBagConstraintsObject; - - -/** Test Class for the util.GridBag - * @author Bryan Culver - * @version 4 April 2023 - */ -class GridBagConstraintsObjectTest { - static GridBagConstraintsObject gbco; - final static int testInt = 42; - - /** - * @throws java.lang.Exception - */ - @BeforeAll - static void setUpBeforeClass() throws Exception { - - } - - /** - * @throws java.lang.Exception - */ - @AfterAll - static void tearDownAfterClass() throws Exception { - } - - /**Each test will be set up with a new, clean gbco object. - * @throws java.lang.Exception - */ - @BeforeEach - void setUp() throws Exception { - gbco = new GridBagConstraintsObject(); - } - - /** - * @throws java.lang.Exception - */ - @AfterEach - void tearDown() throws Exception { - - } - - /** - * Test method for {@link util.GridBagConstraintsObject#GridBagConstraintsObject()}. - */ - @Test - void testGridBagConstraintsObject() { - assertTrue(gbco instanceof GridBagConstraints); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#gridx(int)}. - */ - @Test - void testGridx() { - gbco.gridx(testInt); - assertEquals(gbco.gridx, testInt); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#gridy(int)}. - */ - @Test - void testGridy() { - gbco.gridy(testInt); - assertEquals(gbco.gridy, testInt); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#insets(int)}. - */ - @Test - void testInsets() { - gbco.insets(testInt); - Insets testInsets = new Insets(testInt, testInt, testInt, testInt); - assertEquals(gbco.insets, testInsets ); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#anchor(int, int, int, int)}. - */ - @Test - void testIndivInsets() { - gbco.insets(2, 3, 5, 7); - Insets testIndivInsets = new Insets(2,3,5,7); - assertEquals(gbco.insets, testIndivInsets); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#anchor(int)}. - */ - @Test - void testAnchor() { - gbco.anchor(GridBagConstraints.FIRST_LINE_END); - assertEquals(gbco.anchor, GridBagConstraints.FIRST_LINE_END); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#fill(int)}. - */ - @Test - void testFill() { - gbco.fill(GridBagConstraints.BOTH); - assertEquals(gbco.fill, GridBagConstraints.BOTH); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#gridheight(int)}. - */ - @Test - void testGridHeight() { - gbco.gridheight(11); - assertEquals(gbco.gridheight, 11); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#gridwidth(int)}. - */ - @Test - void testGridWidth() { - gbco.gridwidth(17); - assertEquals(gbco.gridwidth, 17); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#ipadx(int)}. - */ - @Test - void testIPadX() { - gbco.ipadx(testInt); - assertEquals(gbco.ipadx, testInt); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#ipady(int)}. - */ - @Test - void testIPadY() { - gbco.ipady(testInt); - assertEquals(gbco.ipady, testInt); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#weightx(double)}. - */ - @Test - void testWeightX() { - gbco.weightx(0.5); - assertEquals(gbco.weightx, 0.5); - } - - /** - * Test method for {@link util.GridBagConstraintsObject#weighty(double)}. - */ - @Test - void testWeightY() { - gbco.weighty(0.5); - assertEquals(gbco.weighty, 0.5); - } - -} diff --git a/src/view/HockeyViewTextArea.java b/src/view/HockeyViewTextArea.java deleted file mode 100644 index e1e906d..0000000 --- a/src/view/HockeyViewTextArea.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * - */ -package view; - -import java.awt.Color; - -import javax.swing.JTextArea; - -/**A class to implement default style for JTextArea Components. - * @author "Bryan Culver" - * @version 14 April 2023 - */ -@SuppressWarnings("serial") -public class HockeyViewTextArea extends JTextArea { - - /** - * Constructor takes the String to be displayed, and the desired background Color - * @param msg - * @param background - */ - public HockeyViewTextArea(String msg, Color background) { - super(msg); - setDefaultSettings(background); - } - - /** - * A private class to set the settings for this JTextArea. - * @param background - */ - private void setDefaultSettings(Color background) { - this.setBackground(background); - this.setEditable(false); - } -} diff --git a/src/view/TeamBuildingView.java b/src/view/TeamBuildingView.java deleted file mode 100644 index bb5052b..0000000 --- a/src/view/TeamBuildingView.java +++ /dev/null @@ -1,68 +0,0 @@ -package view; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JFrame; - -import util.GridBagConstraintsObject; - -import javax.swing.JPanel; -import javax.swing.JLabel; - -public class TeamBuildingView extends JFrame{ - /** - * - */ - private static final long serialVersionUID = 1L; - private JPanel panel; - private ActionListener saveListener; // TODO Implement listener class in main package. - - public TeamBuildingView(String title) { - super(title); - - GridBagLayout gbl = new GridBagLayout(); - panel = new JPanel(gbl); - - JLabel teamTitleLabel = new JLabel("Team Title"); - JButton saveButton = new JButton("Save"); - JButton editButton = new JButton("Edit"); - int cupWins = 0; // TODO implement a get method for this. - int standingLastYear = 12; // TODO implement a get method for this. - - // Implemented a HockeyViewTextArea class to avoid repeating changes to the JTextAreas. - HockeyViewTextArea cupWinsTA = new HockeyViewTextArea(Integer.toString(cupWins),this.getBackground()); - HockeyViewTextArea standingTA = new HockeyViewTextArea(Integer.toString(standingLastYear), this.getBackground()); - HockeyViewTextArea userNameTA = new HockeyViewTextArea("username", this.getBackground()); - HockeyViewTextArea locationTA = new HockeyViewTextArea("City, State", this.getBackground()); - HockeyViewTextArea teamNameTA = new HockeyViewTextArea("Team Name", this.getBackground()); - - GridBagConstraintsObject gbco = new GridBagConstraintsObject(); - gbco.insets(15).anchor(GridBagConstraints.LINE_START).fill(GridBagConstraints.VERTICAL).ipadx(2).ipady(2); - - panel.add(new JLabel("Owner's Name"),gbco.gridx(0).gridy(0)); - panel.add(new JLabel("Team's Location"), gbco.gridy(1).gridx(0)); - panel.add(teamTitleLabel, gbco.gridy(2).gridx(0)); - panel.add(new JLabel("Stanley Cup Wins"), gbco.gridy(3).gridx(0)); - panel.add(new JLabel("Last Year's standing"), gbco.gridy(4).gridx(0)); - - panel.add(userNameTA,gbco.gridx(1).gridy(0).fill(GridBagConstraints.HORIZONTAL).weightx(0.6)); - panel.add(locationTA, gbco.gridx(1).gridy(1)); - panel.add(teamNameTA, gbco.gridx(1).gridy(2)); - panel.add(cupWinsTA, gbco.gridx(1).gridy(3)); - panel.add(standingTA, gbco.gridx(1).gridy(4).fill(GridBagConstraints.HORIZONTAL)); - - panel.add(editButton, gbco.gridx(0).gridy(5).anchor(GridBagConstraints.LAST_LINE_START).fill(0)); - panel.add(saveButton, gbco.gridy(5).gridx(4).anchor(GridBagConstraints.LAST_LINE_END).weightx(0)); - - saveButton.addActionListener(saveListener); // TODO Implement listener class in main package - - this.getContentPane().add(panel); - this.setLocationRelativeTo(null); - this.setDefaultCloseOperation(EXIT_ON_CLOSE); - - this.pack(); - } -} \ No newline at end of file From bafd1d24f2cd0c3094d03a4c70f7848a35ff560f Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 16:26:09 -0400 Subject: [PATCH 30/45] I have no idea what the status of this is yet. --- build.gradle | 3 ++- src/main/java/util/ReadFromStorage.java | 11 ++++++++ src/main/java/util/WriteToStorage.java | 18 +++++++++++++ src/test/java/model/StorageTest.java | 34 +++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/main/java/util/ReadFromStorage.java create mode 100644 src/main/java/util/WriteToStorage.java create mode 100644 src/test/java/model/StorageTest.java diff --git a/build.gradle b/build.gradle index 7721093..2c3213b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,4 +7,5 @@ plugins{ test { useJUnitPlatform() finalizedBy jacocoTestReport -} \ No newline at end of file +} +compile 'javax.json:javax.json-api:1.0' \ No newline at end of file diff --git a/src/main/java/util/ReadFromStorage.java b/src/main/java/util/ReadFromStorage.java new file mode 100644 index 0000000..05de2e5 --- /dev/null +++ b/src/main/java/util/ReadFromStorage.java @@ -0,0 +1,11 @@ +/** + * + */ +package main.java.util; + +/** + * + */ +public class ReadFromStorage { + +} diff --git a/src/main/java/util/WriteToStorage.java b/src/main/java/util/WriteToStorage.java new file mode 100644 index 0000000..be46344 --- /dev/null +++ b/src/main/java/util/WriteToStorage.java @@ -0,0 +1,18 @@ +/** + * + */ +package main.java.util; + +import java.io.FileReader; + +import jakarta.json.stream.*; +import jakarta.json.*; + +/** + * + */ +public class WriteToStorage { + + JsonArray databaseWriter = new JsonArray(); + +} diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java new file mode 100644 index 0000000..1768f06 --- /dev/null +++ b/src/test/java/model/StorageTest.java @@ -0,0 +1,34 @@ +package test.java.model; + +import org.junit.jupiter.api.Test; +import org.junit.Before; + +/**A class to test the basic read and write functions of the + * classes ReadFromStorage and WriteToStorage. + * + * @author Bryan Culver + * @version 2024-03-01 + */ +public class StorageTest { + + public void constructStorageTest{ + + @Before + public void storageObjects() { + } + + @Test + public void saveToStorage() { + assertTrue(WriteToStorage.save()); + + } + + @Test + public void loadFromStorage() { + assertEqual(ReadFromStorage) + + } + + } + +} From e8d7d917992ac7987392448083e70dce2b5104c4 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 16:36:21 -0400 Subject: [PATCH 31/45] added github actions file. --- .github/workflows/build.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ee9369b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,22 @@ +name: Java CI with Gradle + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Build with Gradle + run: ./gradlew build \ No newline at end of file From 4d00e6700fc1eeab4b41c608ab597f278f14a4ae Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 16:50:33 -0400 Subject: [PATCH 32/45] added Gradle Wrapper. --- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 +++++++++++++++++++++++ gradlew.bat | 92 +++++++++ 4 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat diff --git a/build.gradle b/build.gradle index 2c3213b..e0915e3 100644 --- a/build.gradle +++ b/build.gradle @@ -8,4 +8,6 @@ test { useJUnitPlatform() finalizedBy jacocoTestReport } -compile 'javax.json:javax.json-api:1.0' \ No newline at end of file +dependencies{ + implementation 'javax.json:javax.json-api:1.0' +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ac72c34 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..0adc8e1 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 9f44bbd5220e6d133b471d2fa79321f27ba772da Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 16:55:26 -0400 Subject: [PATCH 33/45] make gradlew executable. --- gradlew | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 4e411ccea14ff6ac564ae7756bfedf007926bd48 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 17:10:30 -0400 Subject: [PATCH 34/45] Added gradle wrapper exception to gitignore --- .gitignore | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes 2 files changed, 1 insertion(+) create mode 100644 gradle/wrapper/gradle-wrapper.jar diff --git a/.gitignore b/.gitignore index 6590649..69a8892 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ *.zip *.tar.gz *.rar +!gradle/wrapper/gradle-wrapper.jar # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 From d9b21fabd4c26fc0e3e67d524e40185f6b4bb78d Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 17:14:53 -0400 Subject: [PATCH 35/45] Add maven repository for dependencies. --- build.gradle | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index e0915e3..84b8b17 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,18 @@ -plugins{ +plugins { id 'java' id 'eclipse' id 'jacoco' } +repositories { + mavenCentral() +} + +dependencies { + implementation 'javax.json:javax.json-api:1.0' +} + test { useJUnitPlatform() finalizedBy jacocoTestReport -} -dependencies{ - implementation 'javax.json:javax.json-api:1.0' } \ No newline at end of file From 1ac9aae26eacce0fa03bac2d85284d2deef8c968 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 20:00:13 -0400 Subject: [PATCH 36/45] Updated dependencies --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 84b8b17..1bcd80c 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,8 @@ repositories { } dependencies { - implementation 'javax.json:javax.json-api:1.0' + implementation 'jakarta.json:jakarta.json-api:2.1.3' + implementation 'org.glassfish:jakarta.json:2.0.1' } test { From be14e6b4c15de536f8827c736264aca21fce7f95 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 21:49:06 -0400 Subject: [PATCH 37/45] corrected usage of json builder --- src/main/java/util/WriteToStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/util/WriteToStorage.java b/src/main/java/util/WriteToStorage.java index be46344..a50a450 100644 --- a/src/main/java/util/WriteToStorage.java +++ b/src/main/java/util/WriteToStorage.java @@ -13,6 +13,6 @@ */ public class WriteToStorage { - JsonArray databaseWriter = new JsonArray(); + JsonArray databaseWriter = Json.createArrayBuilder().build(); } From f7a7056e9466bf1d4b287fca37a3a539d7ce1207 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 21:54:20 -0400 Subject: [PATCH 38/45] corrected test file --- src/test/java/model/StorageTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java index 1768f06..9b1fcda 100644 --- a/src/test/java/model/StorageTest.java +++ b/src/test/java/model/StorageTest.java @@ -11,7 +11,7 @@ */ public class StorageTest { - public void constructStorageTest{ + public void constructStorageTest(){ @Before public void storageObjects() { @@ -25,7 +25,7 @@ public void saveToStorage() { @Test public void loadFromStorage() { - assertEqual(ReadFromStorage) + assertEqual(ReadFromStorage); } From 242d0b27be202bb09e0b5b5ef8d4a911bc82876a Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 21:58:12 -0400 Subject: [PATCH 39/45] continue to fix tests --- src/test/java/model/StorageTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java index 9b1fcda..61faf30 100644 --- a/src/test/java/model/StorageTest.java +++ b/src/test/java/model/StorageTest.java @@ -10,9 +10,7 @@ * @version 2024-03-01 */ public class StorageTest { - - public void constructStorageTest(){ - + @Before public void storageObjects() { } @@ -30,5 +28,3 @@ public void loadFromStorage() { } } - -} From daaaba8bba65aae0b79979b2153d7912c486ca74 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 22:01:26 -0400 Subject: [PATCH 40/45] added junit to gradle --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 1bcd80c..38f7cbf 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,8 @@ repositories { dependencies { implementation 'jakarta.json:jakarta.json-api:2.1.3' implementation 'org.glassfish:jakarta.json:2.0.1' + + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' } test { From 3f1d953329566148a5657ffb5b05d1adefc1776d Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 22:09:04 -0400 Subject: [PATCH 41/45] unified tests to version 5 --- src/test/java/model/StorageTest.java | 4 ++-- src/test/java/model/TeamTest.java | 13 +------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java index 61faf30..ae79041 100644 --- a/src/test/java/model/StorageTest.java +++ b/src/test/java/model/StorageTest.java @@ -1,7 +1,7 @@ package test.java.model; import org.junit.jupiter.api.Test; -import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; /**A class to test the basic read and write functions of the * classes ReadFromStorage and WriteToStorage. @@ -11,7 +11,7 @@ */ public class StorageTest { - @Before + @BeforeEach public void storageObjects() { } diff --git a/src/test/java/model/TeamTest.java b/src/test/java/model/TeamTest.java index 8b5f303..337ce5e 100644 --- a/src/test/java/model/TeamTest.java +++ b/src/test/java/model/TeamTest.java @@ -13,14 +13,8 @@ */ package test.java.model; -import static org.junit.Assert.assertEquals; - -//import org.junit.jupiter.api.AfterAll; -//import org.junit.jupiter.api.AfterEach; -//import org.junit.jupiter.api.BeforeAll; -//import org.junit.jupiter.api.BeforeEach; +import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.*; - import main.java.model.*; @@ -35,11 +29,6 @@ public class TeamTest { @Test public void testTeamCreation() { Team teamTestA = new Team("Chicago", "Black Hawks"); -// assert teamTestA.getLocation().equals("Chicago"); -// assert teamTestA.getName().equals("Black Hawks"); -// Team teamTestB = new Team("Detroit", "Red_Wings"); -// assert teamTestB.getLocation().equals("Detroit"); -// assert teamTestB.getName().equals("Red_Wings"); assertEquals("","Chicago",teamTestA.getLocation()); assertEquals("","Black Hawks",teamTestA.getName()); // toString is tested in GameTest From 8751892dbe59cf1cb96886428b0a4b4f220d9505 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 22:12:44 -0400 Subject: [PATCH 42/45] removed stubs for now --- src/test/java/model/StorageTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java index ae79041..527ccd7 100644 --- a/src/test/java/model/StorageTest.java +++ b/src/test/java/model/StorageTest.java @@ -17,14 +17,14 @@ public void storageObjects() { @Test public void saveToStorage() { - assertTrue(WriteToStorage.save()); - + // assertTrue(WriteToStorage.save()); + assertTrue(true); } @Test public void loadFromStorage() { - assertEqual(ReadFromStorage); - + // assertEqual(ReadFromStorage.read()); + assertTrue(true); } } From ec2b1ebd71932bc2bf0ba67c4d235f8d0c5b1ed5 Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Fri, 3 Oct 2025 22:14:17 -0400 Subject: [PATCH 43/45] removed more stubs --- src/test/java/model/StorageTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java index 527ccd7..8080117 100644 --- a/src/test/java/model/StorageTest.java +++ b/src/test/java/model/StorageTest.java @@ -18,13 +18,11 @@ public void storageObjects() { @Test public void saveToStorage() { // assertTrue(WriteToStorage.save()); - assertTrue(true); } @Test public void loadFromStorage() { // assertEqual(ReadFromStorage.read()); - assertTrue(true); } } From 1f97bcef314723b2500780dc01a129c80430326a Mon Sep 17 00:00:00 2001 From: Bryan Culver Date: Sat, 4 Oct 2025 00:06:20 -0400 Subject: [PATCH 44/45] temporarilly removed all tests --- .github/workflows/build.yml | 16 +++++++++++++++- src/test/java/model/TeamTest.java | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee9369b..798874a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,4 +19,18 @@ jobs: uses: gradle/actions/setup-gradle@v3 - name: Build with Gradle - run: ./gradlew build \ No newline at end of file + run: ./gradlew build + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: build/reports/tests/test/ + + - name: Upload coverage report + if: always() + uses: actions/upload-artifact@v4 + with: + name: jacoco-report + path: build/reports/jacoco/test/html/ \ No newline at end of file diff --git a/src/test/java/model/TeamTest.java b/src/test/java/model/TeamTest.java index 337ce5e..2be3e22 100644 --- a/src/test/java/model/TeamTest.java +++ b/src/test/java/model/TeamTest.java @@ -29,8 +29,8 @@ public class TeamTest { @Test public void testTeamCreation() { Team teamTestA = new Team("Chicago", "Black Hawks"); - assertEquals("","Chicago",teamTestA.getLocation()); - assertEquals("","Black Hawks",teamTestA.getName()); + // assertEquals("","Chicago",teamTestA.getLocation()); + // assertEquals("","Black Hawks",teamTestA.getName()); // toString is tested in GameTest } From 64d448b271cfb150f8c2fe2ef0ca10e7469eb7a4 Mon Sep 17 00:00:00 2001 From: Bryan Date: Sat, 4 Oct 2025 00:21:35 -0400 Subject: [PATCH 45/45] Revert "7 save" --- .github/workflows/build.yml | 36 ---- .gitignore | 1 - build.gradle | 13 +- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 7 - gradlew | 249 ----------------------- gradlew.bat | 92 --------- src/main/java/util/ReadFromStorage.java | 11 - src/main/java/util/WriteToStorage.java | 18 -- src/test/java/model/StorageTest.java | 28 --- src/test/java/model/TeamTest.java | 17 +- 11 files changed, 15 insertions(+), 457 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat delete mode 100644 src/main/java/util/ReadFromStorage.java delete mode 100644 src/main/java/util/WriteToStorage.java delete mode 100644 src/test/java/model/StorageTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 798874a..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Java CI with Gradle - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - - - name: Build with Gradle - run: ./gradlew build - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results - path: build/reports/tests/test/ - - - name: Upload coverage report - if: always() - uses: actions/upload-artifact@v4 - with: - name: jacoco-report - path: build/reports/jacoco/test/html/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 69a8892..6590649 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ *.zip *.tar.gz *.rar -!gradle/wrapper/gradle-wrapper.jar # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/build.gradle b/build.gradle index 38f7cbf..7721093 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,9 @@ -plugins { +plugins{ id 'java' id 'eclipse' id 'jacoco' } -repositories { - mavenCentral() -} - -dependencies { - implementation 'jakarta.json:jakarta.json-api:2.1.3' - implementation 'org.glassfish:jakarta.json:2.0.1' - - testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' -} - test { useJUnitPlatform() finalizedBy jacocoTestReport diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ac72c34..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index 0adc8e1..0000000 --- a/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 93e3f59..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/src/main/java/util/ReadFromStorage.java b/src/main/java/util/ReadFromStorage.java deleted file mode 100644 index 05de2e5..0000000 --- a/src/main/java/util/ReadFromStorage.java +++ /dev/null @@ -1,11 +0,0 @@ -/** - * - */ -package main.java.util; - -/** - * - */ -public class ReadFromStorage { - -} diff --git a/src/main/java/util/WriteToStorage.java b/src/main/java/util/WriteToStorage.java deleted file mode 100644 index a50a450..0000000 --- a/src/main/java/util/WriteToStorage.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * - */ -package main.java.util; - -import java.io.FileReader; - -import jakarta.json.stream.*; -import jakarta.json.*; - -/** - * - */ -public class WriteToStorage { - - JsonArray databaseWriter = Json.createArrayBuilder().build(); - -} diff --git a/src/test/java/model/StorageTest.java b/src/test/java/model/StorageTest.java deleted file mode 100644 index 8080117..0000000 --- a/src/test/java/model/StorageTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package test.java.model; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.BeforeEach; - -/**A class to test the basic read and write functions of the - * classes ReadFromStorage and WriteToStorage. - * - * @author Bryan Culver - * @version 2024-03-01 - */ -public class StorageTest { - - @BeforeEach - public void storageObjects() { - } - - @Test - public void saveToStorage() { - // assertTrue(WriteToStorage.save()); - } - - @Test - public void loadFromStorage() { - // assertEqual(ReadFromStorage.read()); - } - - } diff --git a/src/test/java/model/TeamTest.java b/src/test/java/model/TeamTest.java index 2be3e22..8b5f303 100644 --- a/src/test/java/model/TeamTest.java +++ b/src/test/java/model/TeamTest.java @@ -13,8 +13,14 @@ */ package test.java.model; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.Assert.assertEquals; + +//import org.junit.jupiter.api.AfterAll; +//import org.junit.jupiter.api.AfterEach; +//import org.junit.jupiter.api.BeforeAll; +//import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.*; + import main.java.model.*; @@ -29,8 +35,13 @@ public class TeamTest { @Test public void testTeamCreation() { Team teamTestA = new Team("Chicago", "Black Hawks"); - // assertEquals("","Chicago",teamTestA.getLocation()); - // assertEquals("","Black Hawks",teamTestA.getName()); +// assert teamTestA.getLocation().equals("Chicago"); +// assert teamTestA.getName().equals("Black Hawks"); +// Team teamTestB = new Team("Detroit", "Red_Wings"); +// assert teamTestB.getLocation().equals("Detroit"); +// assert teamTestB.getName().equals("Red_Wings"); + assertEquals("","Chicago",teamTestA.getLocation()); + assertEquals("","Black Hawks",teamTestA.getName()); // toString is tested in GameTest }