commit c0b1dcc45a9ad28297172fdacac8b0a8035de713
parent c8cf3c064984f3cfcf378082f0332c4c41019778
Author: lukeeeeeee334 <lukeosullivan123@gmail.com>
Date: Tue, 19 Nov 2024 10:57:43 +0000
score.java, allscore.java and mainpanel.java
added some functionality to the main panel board, got the personal score and the leader board working.
Diffstat:
3 files changed, 245 insertions(+), 136 deletions(-)
diff --git a/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/MainContentPanel.java b/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/MainContentPanel.java
@@ -1,64 +1,47 @@
-/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
- */
package com.groupproject.tictactoeclient.ContentPanes;
import com.groupproject.tictactoeclient.TicTacToeClient;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import javax.swing.JButton;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.SpringLayout;
-import javax.swing.Timer;
+import javax.swing.*;
/**
- *
- * @author William and Adam
- * Contains the content visible in the main program.
+ * MainContentPanel contains the content visible in the main program.
*/
-
-
public class MainContentPanel extends CustomPanel {
-
-
+
TicTacToeClient client;
JList<String> openGamesList;
-
+
private JLabel gameTimerLabel;
private Timer timer;
private int remainingTime;
-
public MainContentPanel(TicTacToeClient client) {
-
this.client = client;
-
- // Set panel layout to spring layout
+
+ // Set panel layout to SpringLayout
SpringLayout layout = new SpringLayout();
setLayout(layout);
-
+
// Create panel components
JButton createGameButton = new JButton("New Game");
- JButton scoreBoardButton = new JButton("Scoreboard");
+ JButton allscoreButton = new JButton("Scoreboard");
JButton joinGameButton = new JButton("Join Game");
openGamesList = new JList<>();
JScrollPane openGamesScrollPane = new JScrollPane(openGamesList);
- TicTacToeGrid grid = new TicTacToeGrid();
+ TicTacToeGrid grid = new TicTacToeGrid(3, 3); // A 3x3 TicTacToe grid
JLabel gameStatusLabel = new JLabel();
gameTimerLabel = new JLabel();
JButton scoreButton = new JButton("View Personal Score");
-
- // set mock data for labels:
- gameStatusLabel.setText("Opponents turn");
+
+ // Set mock data for labels
+ gameStatusLabel.setText("Opponent's turn");
gameTimerLabel.setText("15m 0s");
-
// Add buttons to panel
- add(scoreBoardButton);
+ add(allscoreButton);
add(createGameButton);
add(openGamesScrollPane);
add(joinGameButton);
@@ -66,71 +49,57 @@ public class MainContentPanel extends CustomPanel {
add(gameStatusLabel);
add(gameTimerLabel);
add(scoreButton);
-
- // Add sprint layout constraints
- // create game button constraints
+
+ // SpringLayout constraints
layout.putConstraint(SpringLayout.WEST, createGameButton, 20, SpringLayout.WEST, this);
layout.putConstraint(SpringLayout.NORTH, createGameButton, 10, SpringLayout.NORTH, this);
-
- // scoreboard button constraints
- layout.putConstraint(SpringLayout.WEST, scoreBoardButton, 20, SpringLayout.EAST, createGameButton);
- layout.putConstraint(SpringLayout.NORTH, scoreBoardButton, 0, SpringLayout.NORTH, createGameButton);
-
- // Games list constraints
+
+ layout.putConstraint(SpringLayout.WEST, allscoreButton, 20, SpringLayout.EAST, createGameButton);
+ layout.putConstraint(SpringLayout.NORTH, allscoreButton, 0, SpringLayout.NORTH, createGameButton);
+
layout.putConstraint(SpringLayout.WEST, openGamesScrollPane, 0, SpringLayout.WEST, createGameButton);
- layout.putConstraint(SpringLayout.EAST, openGamesScrollPane, 0, SpringLayout.EAST, scoreBoardButton);
+ layout.putConstraint(SpringLayout.EAST, openGamesScrollPane, 0, SpringLayout.EAST, allscoreButton);
layout.putConstraint(SpringLayout.NORTH, openGamesScrollPane, 10, SpringLayout.SOUTH, createGameButton);
layout.putConstraint(SpringLayout.SOUTH, openGamesScrollPane, -10, SpringLayout.NORTH, joinGameButton);
-
- // join button constraints
+
layout.putConstraint(SpringLayout.WEST, joinGameButton, 20, SpringLayout.WEST, this);
layout.putConstraint(SpringLayout.SOUTH, joinGameButton, -20, SpringLayout.SOUTH, this);
- layout.putConstraint(SpringLayout.EAST, joinGameButton, 0, SpringLayout.EAST, scoreBoardButton);
-
- // Add label constraints
+ layout.putConstraint(SpringLayout.EAST, joinGameButton, 0, SpringLayout.EAST, allscoreButton);
+
layout.putConstraint(SpringLayout.WEST, gameStatusLabel, 0, SpringLayout.WEST, grid);
layout.putConstraint(SpringLayout.NORTH, gameStatusLabel, -20, SpringLayout.NORTH, grid);
layout.putConstraint(SpringLayout.EAST, gameTimerLabel, 0, SpringLayout.EAST, grid);
layout.putConstraint(SpringLayout.NORTH, gameTimerLabel, -20, SpringLayout.NORTH, grid);
-
- // grid constraints
- layout.putConstraint(SpringLayout.WEST, grid, 40, SpringLayout.EAST, scoreBoardButton);
+
+ layout.putConstraint(SpringLayout.WEST, grid, 40, SpringLayout.EAST, allscoreButton);
layout.putConstraint(SpringLayout.NORTH, grid, 40, SpringLayout.NORTH, this);
layout.putConstraint(SpringLayout.SOUTH, grid, 240, SpringLayout.NORTH, this);
layout.putConstraint(SpringLayout.EAST, grid, -20, SpringLayout.EAST, this);
-
- // View score button constraints
+
layout.putConstraint(SpringLayout.SOUTH, scoreButton, -20, SpringLayout.SOUTH, this);
layout.putConstraint(SpringLayout.EAST, scoreButton, -20, SpringLayout.EAST, this);
-
-
- //Create game button action listener
- createGameButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- client.proxy.newGame(Integer.parseInt(client.UID));
-
- //start countdown when create game
- startTimer();
- }
+
+ // Button action listeners
+ createGameButton.addActionListener(e -> {
+ client.proxy.newGame(Integer.parseInt(client.UID));
+ startTimer();
});
-
-
- scoreButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- client.showPanel(new score(client));
-
- //start countdown when create game
- startTimer();
- }
+
+ joinGameButton.addActionListener(e -> {
+ //client.proxy.joinGame(Integer.parseInt(client.UID), Integer.parseInt(client.GID));
+ //startTimer();
+ });
+
+ scoreButton.addActionListener(e -> {
+ client.showPanel(new score(client));
+ startTimer();
+ });
+
+ allscoreButton.addActionListener(e -> {
+ client.showPanel(new allscore(client));
+ startTimer();
});
}
-
-
-
-
-
@Override
public void refresh() {
@@ -141,40 +110,52 @@ public class MainContentPanel extends CustomPanel {
this.revalidate();
this.repaint();
}
-
-
- private void startTimer()
- {
- //remaining time is 15 minutes
+
+ private void startTimer() {
+ // Remaining time is 15 minutes
remainingTime = 15 * 60;
-
- //create timer that updates every 1 seconds i.e countdown clock
- timer = new Timer(1000, new ActionListener(){
- @Override
- public void actionPerformed(ActionEvent e) {
-
- //countdown time
- remainingTime--;
-
- int minutes = remainingTime / 60;
- int seconds = remainingTime % 60;
-
- String time = String.format("%02d:%02d", minutes, seconds);
-
- gameTimerLabel.setText(time);
-
- //need to implement when no one else joins the game
- //and the countdown is finished that the game is then deleted
- //at the moment it just prints game finished
- if(remainingTime <= 0) {
- timer.stop();
- gameTimerLabel.setText("Finished");
- }
+
+ // Create a timer that updates every second
+ timer = new Timer(1000, e -> {
+ // Countdown time
+ remainingTime--;
+
+ int minutes = remainingTime / 60;
+ int seconds = remainingTime % 60;
+
+ String time = String.format("%02d:%02d", minutes, seconds);
+
+ gameTimerLabel.setText(time);
+
+ if (remainingTime <= 0) {
+ timer.stop();
+ gameTimerLabel.setText("Finished");
}
});
- timer.start();
+ timer.start();
+ }
+
+ /**
+ * A custom class for the TicTacToe grid.
+ */
+ class TicTacToeGrid extends JPanel {
+ public TicTacToeGrid(int rows, int cols) {
+ setLayout(new GridLayout(rows, cols, 5, 5)); // Grid with 5px gaps
+
+ for (int i = 0; i < rows * cols; i++) {
+ JButton button = new JButton();
+ button.setFont(new Font("Arial", Font.BOLD, 32)); // Large text for "X"
+ add(button);
+
+ // Add ActionListener for button clicks
+ button.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ button.setText("X");
+ button.setEnabled(false); // Disable the button after it's clicked
+ }
+ });
+ }
+ }
}
-
-
-
-}
-\ No newline at end of file
+}
diff --git a/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/allscore.java b/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/allscore.java
@@ -0,0 +1,122 @@
+package com.groupproject.tictactoeclient.ContentPanes;
+
+import com.groupproject.tictactoeclient.TicTacToeClient;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class to display the scores of all users.
+ */
+public class allscore extends CustomPanel {
+ public allscore(TicTacToeClient client) {
+ // Set SpringLayout
+ SpringLayout layout = new SpringLayout();
+ setLayout(layout);
+
+ // Text Area for displaying scores
+ JTextArea statsArea = new JTextArea();
+ statsArea.setEditable(false);
+ statsArea.setFont(new Font("Monospaced", Font.PLAIN, 14));
+
+ // Add Text Area inside a Scroll Pane
+ JScrollPane scrollPane = new JScrollPane(statsArea);
+ add(scrollPane);
+
+ // Back Button
+ JButton backButton = new JButton("Back");
+ add(backButton);
+
+ // Set constraints for Scroll Pane
+ layout.putConstraint(SpringLayout.NORTH, scrollPane, 10, SpringLayout.NORTH, this);
+ layout.putConstraint(SpringLayout.WEST, scrollPane, 10, SpringLayout.WEST, this);
+ layout.putConstraint(SpringLayout.EAST, scrollPane, -10, SpringLayout.EAST, this);
+ layout.putConstraint(SpringLayout.SOUTH, scrollPane, -50, SpringLayout.SOUTH, this);
+
+ // Set constraints for Back Button
+ layout.putConstraint(SpringLayout.SOUTH, backButton, -10, SpringLayout.SOUTH, this); // 10px above bottom
+ layout.putConstraint(SpringLayout.WEST, backButton, 10, SpringLayout.WEST, this);
+
+ // Populate stats area
+ try {
+ String leagueData = client.proxy.leagueTable();
+ if (leagueData.equals("ERROR-NOGAMES")) {
+ statsArea.setText("No games found.");
+ return;
+ } else if (leagueData.equals("ERROR-DB")) {
+ statsArea.setText("Database error occurred.");
+ return;
+ }
+
+ // Split the result into rows
+ String[] games = leagueData.split("\n");
+ Map<String, int[]> playerStats = new HashMap<>();
+
+ // Parse each game's data
+ for (String game : games) {
+ try {
+ String[] columns = game.split(","); // Assuming data is comma-separated
+ if (columns.length < 4) {
+ throw new IllegalArgumentException("Malformed row: " + game);
+ }
+
+ String player1UID = columns[1].trim(); // Player 1 UID
+ String player2UID = columns[2].trim(); // Player 2 UID
+ String gameState = columns[3].trim(); // Game state as a string
+
+ int gameStateInt = Integer.parseInt(gameState);
+
+ // Update stats for Player 1
+ playerStats.putIfAbsent(player1UID, new int[2]);
+ playerStats.putIfAbsent(player2UID, new int[2]);
+
+ if (gameStateInt == 1) { // Player 1 wins
+ playerStats.get(player1UID)[0]++; // Increment wins for Player 1
+ playerStats.get(player2UID)[1]++; // Increment losses for Player 2
+ } else if (gameStateInt == 2) { // Player 2 wins
+ playerStats.get(player2UID)[0]++; // Increment wins for Player 2
+ playerStats.get(player1UID)[1]++; // Increment losses for Player 1
+ }
+
+ } catch (Exception rowException) {
+ System.err.println("Error processing row: " + game);
+ rowException.printStackTrace();
+ }
+ }
+
+ // Build the display string
+ StringBuilder statsBuilder = new StringBuilder();
+ statsBuilder.append(String.format("%-20s %-10s %-10s\n", "Username", "Wins", "Losses"));
+ statsBuilder.append("-".repeat(40)).append("\n");
+
+ for (Map.Entry<String, int[]> entry : playerStats.entrySet()) {
+ String username = entry.getKey();
+ int wins = entry.getValue()[0];
+ int losses = entry.getValue()[1];
+ statsBuilder.append(String.format("%-20s %-10d %-10d\n", username, wins, losses));
+ }
+
+ statsArea.setText(statsBuilder.toString());
+
+ } catch (Exception e) {
+ statsArea.setText("An error occurred while calculating player stats.");
+ e.printStackTrace();
+ }
+
+ // Back Button Listener
+ backButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ client.showPanel(new MainContentPanel(client));
+ }
+ });
+ }
+
+ @Override
+ public void refresh() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
diff --git a/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/score.java b/TicTacToeClient/src/main/java/com/groupproject/tictactoeclient/ContentPanes/score.java
@@ -3,26 +3,35 @@ package com.groupproject.tictactoeclient.ContentPanes;
import com.groupproject.tictactoeclient.TicTacToeClient;
import javax.swing.*;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
/**
* Class to display the score panel with player stats.
*/
public class score extends CustomPanel {
public score(TicTacToeClient client) {
-//super(); // Call the parent constructor
+ SpringLayout layout = new SpringLayout();
+ setLayout(layout);
- // Get the logged-in UID from the client
- String loggedInUID = client.UID;
- String loggedInUsername = client.username;
- System.out.println("Logged-in UID: " + loggedInUID);
-
- // Panel to display the stats
- setLayout(new BorderLayout());
+ // Label to display stats
JLabel statsLabel = new JLabel();
statsLabel.setHorizontalAlignment(SwingConstants.CENTER);
statsLabel.setFont(new Font("Arial", Font.BOLD, 16));
statsLabel.setForeground(Color.BLACK);
- add(statsLabel, BorderLayout.CENTER);
+ add(statsLabel);
+
+ // Back Button
+ JButton backButton = new JButton("Back");
+ add(backButton);
+
+ // Position the statsLabel (centered horizontally, at the top)
+ layout.putConstraint(SpringLayout.HORIZONTAL_CENTER, statsLabel, 0, SpringLayout.HORIZONTAL_CENTER, this);
+ layout.putConstraint(SpringLayout.NORTH, statsLabel, 20, SpringLayout.NORTH, this);
+
+ // Position the backButton (bottom-left corner)
+ layout.putConstraint(SpringLayout.SOUTH, backButton, -10, SpringLayout.SOUTH, this);
+ layout.putConstraint(SpringLayout.WEST, backButton, 10, SpringLayout.WEST, this);
try {
// Call the leagueTable method to get all games
@@ -53,33 +62,24 @@ public class score extends CustomPanel {
String player1UID = columns[1].trim(); // Player 1 UID
String player2UID = columns[2].trim(); // Player 2 UID
- String gameState = columns[3].trim(); // Game state as a string
+ String gameState = columns[3].trim(); // Game state as a string
- // Convert game state to an integer
int gameStateInt = Integer.parseInt(gameState);
- // Determine results for the logged-in player
-
- // Logged-in player is Player 1
-
- if (player1UID.equals(loggedInUsername)) {
- // Logged-in player is Player 1
+ if (player1UID.equals(client.username)) {
if (gameStateInt == 1) { // Player 1 wins
wins++;
} else if (gameStateInt == 2) { // Player 2 wins
losses++;
}
- } else if (player2UID.equals(loggedInUsername)) {
- // Logged-in player is Player 2
+ } else if (player2UID.equals(client.username)) {
if (gameStateInt == 2) { // Player 2 wins
wins++;
} else if (gameStateInt == 1) { // Player 1 wins
losses++;
}
}
-
-
-
+
} catch (Exception rowException) {
System.err.println("Error processing row: " + game);
rowException.printStackTrace();
@@ -87,12 +87,19 @@ public class score extends CustomPanel {
}
// Display the result as a summary
- statsLabel.setText(String.format("Player %s: Wins = %d, Losses = %d", loggedInUsername, wins, losses));
+ statsLabel.setText(String.format("Player %s: Wins = %d, Losses = %d", client.username, wins, losses));
} catch (Exception e) {
- // Catch any unexpected errors
statsLabel.setText("An error occurred while calculating player stats.");
- e.printStackTrace(); // Log the exception for debugging
+ e.printStackTrace();
}
+
+ // Back Button Action
+ backButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ client.showPanel(new MainContentPanel(client));
+ }
+ });
}
@Override