From a506f2230da83fcb9a07186649405242578a35c9 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 14:05:02 +0200 Subject: [PATCH 01/10] add rudementary quicksave -load --- .../controller/ButtonQuickloadListener.java | 24 + .../controller/ButtonQuicksaveListener.java | 19 + .../de/mannheim/th/chess/domain/Game.java | 22 +- .../de/mannheim/th/chess/ui/SpielFrame.java | 880 +++++++++--------- 4 files changed, 508 insertions(+), 437 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java new file mode 100644 index 0000000..c1cf05b --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java @@ -0,0 +1,24 @@ + +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; + +public class ButtonQuickloadListener implements ActionListener { + private Game game; + private SpielFrame sf; + + public ButtonQuickloadListener(Game game, SpielFrame sf) { + this.game = game; + this.sf = sf; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.quickload(); + this.sf.erstelleBrett(); + } +} diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java new file mode 100644 index 0000000..c73facc --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java @@ -0,0 +1,19 @@ +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; + +public class ButtonQuicksaveListener implements ActionListener { + private Game game; + + public ButtonQuicksaveListener(Game game) { + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.quicksave(); + } +} diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index a65305b..d353a3e 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -33,6 +33,8 @@ public class Game { private String modus; private boolean rotieren, zuruecknahme; + private MoveList savestate; + private MoveList movelist; public Game() { @@ -123,6 +125,20 @@ public class Game { this.movelist.removeLast(); } + public void quicksave() { + logger.info("Quicksaved"); + this.savestate = new MoveList(this.movelist); + } + + public void quickload() { + logger.info("Quickloaded"); + + this.board = new Board(); + for (Move move : savestate) { + this.playMove(move); + } + } + /** * Plays the move on the board and adds it to the movelist * @@ -272,9 +288,9 @@ public class Game { return board.getFen(); } -// public Square getSelectedSquare() { -// return this.getSelectedSquare(); -// } + // public Square getSelectedSquare() { + // return this.getSelectedSquare(); + // } public String getUnicodeFromMove(Move move) { return board.getPiece(move.getTo()).getFanSymbol().toUpperCase(); diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 5dcd7b3..ee3f457 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -14,6 +14,8 @@ import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonAufgebenListener; import de.mannheim.th.chess.controller.ButtonFileSaverListener; import de.mannheim.th.chess.controller.ButtonMovePieceListener; +import de.mannheim.th.chess.controller.ButtonQuickloadListener; +import de.mannheim.th.chess.controller.ButtonQuicksaveListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; import de.mannheim.th.chess.controller.ButtonUndoMoveListener; @@ -44,492 +46,502 @@ import java.awt.GridLayout; public class SpielFrame extends JFrame { - private static final Logger logger = LogManager.getLogger(App.class); + private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private ArrayList buttons = new ArrayList<>(); - private HashMap belegungen = new HashMap<>(); - private JPanel panelLinks, panelRechts, contentPane; - private JButton undo, undo2; - private JTextArea ausgabe; - private Game game; - private Clock clock; - private ArrayList anzeigeMoves = new ArrayList(); - - private BoardMode mode; - private Square selectedSquare; - - public enum BoardMode { - normal, pieceSelected, finished - } - - /** - * Create the frame. - */ - public SpielFrame(Game game) { - - this.game = game; - this.clock = game.getClock(); - this.clock.start(); - - mode = BoardMode.normal; - - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 1920, 1080); - setTitle("Schach"); - setAlwaysOnTop(true); - - contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); - setContentPane(contentPane); - - // Linkes Panel mit GridLayout 8x8 für Schachbrett - panelLinks = new JPanel(new GridLayout(8, 8)); - - erstelleBrett(); - - // Rechtes Panel für Steuerung oder zusätzliche Eingaben - panelRechts = new JPanel(); - panelRechts.setBackground(new Color(90, 90, 90)); - panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); - - // Panel für alle Eingaben von Player 2 - panelRechts.add(getUiPlayerTwo()); - - // Panel für Statistikanzeigen - panelRechts.add(getUiStatistik()); - - // Panel für alle Eingaben von Player 1 - panelRechts.add(getUiPlayerOne()); - - // JSplitPane horizontal (linke und rechte Hälfte) - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); - splitPane.setResizeWeight(0.75); - splitPane.setBackground(Color.BLACK); - splitPane.setDividerSize(1); - splitPane.setEnabled(false); - - contentPane.add(splitPane, BorderLayout.CENTER); - - setVisible(true); - } - - /** - * Erstellt alle Buttons und fügt sie dem Frame hinzu. - */ - public void erstelleBrett() { - - this.clearButtons(); - this.setDefaultBackground(); - this.setButtonsActions(); - - ladeBrett(); - - panelLinks.revalidate(); - panelLinks.repaint(); - - } - - private int mirrowedGrid(int i) { - return 63 - (((i / 8) * 8) + (7 - i % 8)); - } - - /** - * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren - */ - private void ladeBrett() { - // System.out.println(game.toFEN()); - - char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); - int i = 0; - for (int j = 0; j < fen.length; j++) { - if (Character.isDigit(fen[j])) { - int leerfelder = Character.getNumericValue(fen[j]); - for (int k = 0; k < leerfelder; k++) { - belegungen.put(buttons.get(i), "n-n"); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder - // nicht ckickbar sein sollten. - i++; - } - continue; - } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also - belegungen.put(buttons.get(i), "w-" + fen[j]); - } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also - belegungen.put(buttons.get(i), "b-" + fen[j]); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß - // beginnen kann - } - buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - - i++; - - } - } - - /** - * Clears the existing buttons from the button list, panellinks and fills them - * with new blank ones. - */ - private void clearButtons() { - - buttons.clear(); - panelLinks.removeAll(); - - for (int i = 0; i < 64; i++) { - JButton b = new JButton(); - - b.setEnabled(false); - - // style - b.setFocusPainted(false); - b.setFont(new Font("Arial", Font.PLAIN, 30)); - b.setForeground(Color.WHITE); - b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - b.setName(i + ""); - - buttons.add(b); - } - } - - /** - * Sets the default background color for the buttons in the grid. - */ - private void setDefaultBackground() { - for (int i = 0; i < 64; i++) { - JButton b = buttons.get(i); - if ((i / 8 + i % 8) % 2 == 0) { - // logger.info("Helles Feld erstellt." + i); - b.setBackground(new Color(90, 90, 90)); - } else { - // logger.info("Dunkles Feld erstellt." + i); - b.setBackground(new Color(65, 65, 65)); - } - } - } - - /* - * Switches the button actions depending on the boardmode - */ - private void setButtonsActions() { - - List selectables; - - switch (this.mode) { - case BoardMode.normal: - - selectables = game.getAllLegalMoveableSquares(); - - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - b.setEnabled(true); - // b.setBackground(Color.green); - b.addActionListener(new ButtonSelectPieceListener(this, square)); - } - - break; - - case BoardMode.pieceSelected: - - JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); - s.setEnabled(true); - s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); - - selectables = game.getLegalMoveableSquares(selectedSquare); - - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - final Move move = new Move(selectedSquare, square); - b.setEnabled(true); - b.setBackground(new Color(230, 100, 100)); - b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); - } - break; - case finished: - clearButtons(); - break; - default: - break; - - } - - for (JButton b : buttons) { - panelLinks.add(b); - } - } - - public void showDraw() { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); - - // JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - // jl.setBounds(50, 30, 200, 25); - // jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - // frame.add(jl); - // frame.setVisible(true); - } - - public void showWin(int player) { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); - - JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); - } - - public int showPromotion() { - final int[] result = { -1 }; - - JDialog dialog = new JDialog(this, "Wähle eine Figur", true); - dialog.setLayout(new GridLayout(2, 2)); - dialog.setSize(300, 200); - - int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; - - for (int i = 0; i < 4; i++) { - int index = (game.getActivePlayer() - 1) * 4 + i; - JButton jb = new JButton(); - jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); - int selectedPiece = index; - jb.addActionListener(e -> { - System.out.println("Test"); - result[0] = selectedPiece; - dialog.dispose(); - }); - dialog.add(jb); - } - - dialog.setLocationRelativeTo(null); - dialog.setVisible(true); - - return result[0]; - } + private static final long serialVersionUID = 1L; + private ArrayList buttons = new ArrayList<>(); + private HashMap belegungen = new HashMap<>(); + private JPanel panelLinks, panelRechts, contentPane; + private JButton undo, undo2; + private JTextArea ausgabe; + private Game game; + private Clock clock; + private ArrayList anzeigeMoves = new ArrayList(); + + private BoardMode mode; + private Square selectedSquare; + + public enum BoardMode { + normal, pieceSelected, finished + } + + /** + * Create the frame. + */ + public SpielFrame(Game game) { + + this.game = game; + this.clock = game.getClock(); + this.clock.start(); + + mode = BoardMode.normal; + + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 1920, 1080); + setTitle("Schach"); + setAlwaysOnTop(true); + + contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + setContentPane(contentPane); + + // Linkes Panel mit GridLayout 8x8 für Schachbrett + panelLinks = new JPanel(new GridLayout(8, 8)); + + erstelleBrett(); + + // Rechtes Panel für Steuerung oder zusätzliche Eingaben + panelRechts = new JPanel(); + panelRechts.setBackground(new Color(90, 90, 90)); + panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); + + // Panel für alle Eingaben von Player 2 + panelRechts.add(getUiPlayerTwo()); + + // Panel für Statistikanzeigen + panelRechts.add(getUiStatistik()); + + // Panel für alle Eingaben von Player 1 + panelRechts.add(getUiPlayerOne()); + + // JSplitPane horizontal (linke und rechte Hälfte) + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); + splitPane.setResizeWeight(0.75); + splitPane.setBackground(Color.BLACK); + splitPane.setDividerSize(1); + splitPane.setEnabled(false); + + contentPane.add(splitPane, BorderLayout.CENTER); + + setVisible(true); + } + + /** + * Erstellt alle Buttons und fügt sie dem Frame hinzu. + */ + public void erstelleBrett() { + + this.clearButtons(); + this.setDefaultBackground(); + this.setButtonsActions(); + + ladeBrett(); + + panelLinks.revalidate(); + panelLinks.repaint(); + + } + + private int mirrowedGrid(int i) { + return 63 - (((i / 8) * 8) + (7 - i % 8)); + } + + /** + * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren + */ + private void ladeBrett() { + // System.out.println(game.toFEN()); + + char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); + int i = 0; + for (int j = 0; j < fen.length; j++) { + if (Character.isDigit(fen[j])) { + int leerfelder = Character.getNumericValue(fen[j]); + for (int k = 0; k < leerfelder; k++) { + belegungen.put(buttons.get(i), "n-n"); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder + // nicht ckickbar sein sollten. + i++; + } + continue; + } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also + belegungen.put(buttons.get(i), "w-" + fen[j]); + } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also + belegungen.put(buttons.get(i), "b-" + fen[j]); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß + // beginnen kann + } + buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + + i++; + + } + } + + /** + * Clears the existing buttons from the button list, panellinks and fills them + * with new blank ones. + */ + private void clearButtons() { + + buttons.clear(); + panelLinks.removeAll(); + + for (int i = 0; i < 64; i++) { + JButton b = new JButton(); + + b.setEnabled(false); + + // style + b.setFocusPainted(false); + b.setFont(new Font("Arial", Font.PLAIN, 30)); + b.setForeground(Color.WHITE); + b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + b.setName(i + ""); + + buttons.add(b); + } + } + + /** + * Sets the default background color for the buttons in the grid. + */ + private void setDefaultBackground() { + for (int i = 0; i < 64; i++) { + JButton b = buttons.get(i); + if ((i / 8 + i % 8) % 2 == 0) { + // logger.info("Helles Feld erstellt." + i); + b.setBackground(new Color(90, 90, 90)); + } else { + // logger.info("Dunkles Feld erstellt." + i); + b.setBackground(new Color(65, 65, 65)); + } + } + } + + /* + * Switches the button actions depending on the boardmode + */ + private void setButtonsActions() { + + List selectables; + + switch (this.mode) { + case BoardMode.normal: + + selectables = game.getAllLegalMoveableSquares(); + + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + b.setEnabled(true); + // b.setBackground(Color.green); + b.addActionListener(new ButtonSelectPieceListener(this, square)); + } + + break; + + case BoardMode.pieceSelected: + + JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); + s.setEnabled(true); + s.setBackground(new Color(165, 42, 42)); + s.addActionListener(new ButtonToNormalListener(this)); + + selectables = game.getLegalMoveableSquares(selectedSquare); + + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + final Move move = new Move(selectedSquare, square); + b.setEnabled(true); + b.setBackground(new Color(230, 100, 100)); + b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); + } + break; + case finished: + clearButtons(); + break; + default: + break; + + } + + for (JButton b : buttons) { + panelLinks.add(b); + } + } + + public void showDraw() { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + // JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + // jl.setBounds(50, 30, 200, 25); + // jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + // frame.add(jl); + // frame.setVisible(true); + } + + public void showWin(int player) { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); + } + + public int showPromotion() { + final int[] result = { -1 }; + + JDialog dialog = new JDialog(this, "Wähle eine Figur", true); + dialog.setLayout(new GridLayout(2, 2)); + dialog.setSize(300, 200); + + int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; + + for (int i = 0; i < 4; i++) { + int index = (game.getActivePlayer() - 1) * 4 + i; + JButton jb = new JButton(); + jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); + int selectedPiece = index; + jb.addActionListener(e -> { + System.out.println("Test"); + result[0] = selectedPiece; + dialog.dispose(); + }); + dialog.add(jb); + } + + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + + return result[0]; + } + + private JPanel getUiPlayerTwo() { + + JPanel playerTwo = new JPanel(); + playerTwo.setBackground(new Color(90, 90, 90)); + playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); + + playerTwo.add(Box.createVerticalStrut(15)); + + JLabel pl2 = new JLabel("Player 2:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerTwo.add(pl2); + + playerTwo.add(Box.createVerticalStrut(10)); + + JLabel clock1 = clock.getClock2(); + playerTwo.add(clock1); + + playerTwo.add(Box.createVerticalStrut(10)); + + // Button zurücknahme und aufgeben für Player 2 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + + if (game.isZuruecknahme()) { + undo = new JButton("Zug zurücknehmen"); + undo.setBackground(Color.LIGHT_GRAY); + undo.setForeground(Color.BLACK); + undo.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo); - private JPanel getUiPlayerTwo() { - - JPanel playerTwo = new JPanel(); - playerTwo.setBackground(new Color(90, 90, 90)); - playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); - - playerTwo.add(Box.createVerticalStrut(15)); - - JLabel pl2 = new JLabel("Player 2:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerTwo.add(pl2); - - playerTwo.add(Box.createVerticalStrut(10)); - - JLabel clock1 = clock.getClock2(); - playerTwo.add(clock1); - - playerTwo.add(Box.createVerticalStrut(10)); - - // Button zurücknahme und aufgeben für Player 2 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - - if (game.isZuruecknahme()) { - undo = new JButton("Zug zurücknehmen"); - undo.setBackground(Color.LIGHT_GRAY); - undo.setForeground(Color.BLACK); - undo.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo); + // Button-Listener + undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } - // Button-Listener - undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); - } + aufgebenUndo.add(Box.createHorizontalStrut(10)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + playerTwo.add(aufgebenUndo); - playerTwo.add(aufgebenUndo); + playerTwo.add(Box.createVerticalStrut(10)); - playerTwo.add(Box.createVerticalStrut(10)); + return playerTwo; + } - return playerTwo; - } + private JPanel getUiStatistik() { - private JPanel getUiStatistik() { + JPanel statistik = new JPanel(); + statistik.setBackground(new Color(90, 90, 90)); + statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); - JPanel statistik = new JPanel(); - statistik.setBackground(new Color(90, 90, 90)); - statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); + ausgabe = new JTextArea(); + ausgabe.setEditable(false); + ausgabe.setBackground(new Color(75, 75, 75)); + ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); + ausgabe.setForeground(Color.BLACK); + ausgabe.setText("\n Bisherige Züge:\n"); - ausgabe = new JTextArea(); - ausgabe.setEditable(false); - ausgabe.setBackground(new Color(75, 75, 75)); - ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); - ausgabe.setForeground(Color.BLACK); - ausgabe.setText("\n Bisherige Züge:\n"); + JScrollPane scrollPane = new JScrollPane(ausgabe); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - JScrollPane scrollPane = new JScrollPane(ausgabe); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + statistik.add(scrollPane); - statistik.add(scrollPane); + JButton quicksave = new JButton(); + quicksave.addActionListener(new ButtonQuicksaveListener(this.game)); + quicksave.setText("Quicksave"); + statistik.add(quicksave); - return statistik; - } + JButton quickload = new JButton(); + quickload.addActionListener(new ButtonQuickloadListener(this.game, this)); + quickload.setText("Quickload"); + statistik.add(quickload); - public void aktualisiereAusgabe() { + return statistik; + } - StringBuilder sb = new StringBuilder(); - sb.append("\n Bisherige Züge:\n"); + public void aktualisiereAusgabe() { - MoveList l = game.getMoveList(); - anzeigeMoves.add(" " + game.getUnicodeFromMove(l.getLast()) + ": " + l.getLast().toString() + "\n"); + StringBuilder sb = new StringBuilder(); + sb.append("\n Bisherige Züge:\n"); - for (String line : anzeigeMoves) { - sb.append(line); - } + MoveList l = game.getMoveList(); + anzeigeMoves.add(" " + game.getUnicodeFromMove(l.getLast()) + ": " + l.getLast().toString() + "\n"); - ausgabe.setText(sb.toString()); - } + for (String line : anzeigeMoves) { + sb.append(line); + } - public void deleteLastAusgabe() { - String[] zeilen = ausgabe.getText().split("\n"); + ausgabe.setText(sb.toString()); + } - // es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist - if (zeilen.length <= 2) - return; + public void deleteLastAusgabe() { + String[] zeilen = ausgabe.getText().split("\n"); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < zeilen.length - 1; i++) { - sb.append(zeilen[i]).append("\n"); - } + // es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist + if (zeilen.length <= 2) + return; - ausgabe.setText(sb.toString()); - } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < zeilen.length - 1; i++) { + sb.append(zeilen[i]).append("\n"); + } - private JPanel getUiPlayerOne() { + ausgabe.setText(sb.toString()); + } - JPanel playerOne = new JPanel(); - playerOne.setBackground(new Color(90, 90, 90)); - playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); + private JPanel getUiPlayerOne() { - playerOne.add(Box.createVerticalStrut(10)); + JPanel playerOne = new JPanel(); + playerOne.setBackground(new Color(90, 90, 90)); + playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); - // Button zurücknahme und aufgeben für Player 1 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + playerOne.add(Box.createVerticalStrut(10)); - if (game.isZuruecknahme()) { - undo2 = new JButton("Zug zurücknehmen"); - undo2.setBackground(Color.LIGHT_GRAY); - undo2.setForeground(Color.BLACK); - undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo2.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo2); + // Button zurücknahme und aufgeben für Player 1 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - // Button-Listener - undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); + if (game.isZuruecknahme()) { + undo2 = new JButton("Zug zurücknehmen"); + undo2.setBackground(Color.LIGHT_GRAY); + undo2.setForeground(Color.BLACK); + undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo2.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo2); - } + // Button-Listener + undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + } - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - playerOne.add(aufgebenUndo); + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - playerOne.add(Box.createVerticalStrut(15)); + playerOne.add(aufgebenUndo); - JLabel clock1 = clock.getClock1(); - playerOne.add(clock1); + playerOne.add(Box.createVerticalStrut(15)); - playerOne.add(Box.createVerticalStrut(10)); + JLabel clock1 = clock.getClock1(); + playerOne.add(clock1); - JLabel pl2 = new JLabel("Player 1:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerOne.add(pl2); + playerOne.add(Box.createVerticalStrut(10)); - return playerOne; - } + JLabel pl2 = new JLabel("Player 1:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerOne.add(pl2); - public void setBoardMode(BoardMode bm) { - this.mode = bm; - } + return playerOne; + } - public void setSelectedSquare(Square sq) { - this.selectedSquare = sq; - } + public void setBoardMode(BoardMode bm) { + this.mode = bm; + } - public HashMap getBelegung() { - return this.belegungen; - } + public void setSelectedSquare(Square sq) { + this.selectedSquare = sq; + } - public JButton getUndo() { - return undo; - } + public HashMap getBelegung() { + return this.belegungen; + } - public JButton getUndo2() { - return undo2; - } + public JButton getUndo() { + return undo; + } - public BoardMode getMode() { - return mode; - } + public JButton getUndo2() { + return undo2; + } - public Clock getClock() { - return clock; - } + public BoardMode getMode() { + return mode; + } + + public Clock getClock() { + return clock; + } } From ff893396fe2a65bad76decf14d3f0c073d3c0cc4 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 15:01:17 +0200 Subject: [PATCH 02/10] add support for custom start positions --- .../de/mannheim/th/chess/domain/Game.java | 43 +++++++++++++------ .../de/mannheim/th/chess/ui/SpielFrame.java | 1 + 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index d353a3e..c73ce72 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -33,21 +33,24 @@ public class Game { private String modus; private boolean rotieren, zuruecknahme; - private MoveList savestate; - private MoveList movelist; - public Game() { - - this.board = new Board(); - this.movelist = new MoveList(); - clock = new Clock("blitz"); - clock.start(); - } + private MoveList savestate; + private String startPosFen; /** * Conststructs a new standard GameBoard. */ + public Game() { + + this.board = new Board(); + this.movelist = new MoveList(); + this.startPosFen = this.board.getFen(); + + clock = new Clock("blitz"); + clock.start(); + } + public Game(String modus, boolean rotieren, boolean zuruecknahme, String fen) { this.modus = modus; this.rotieren = rotieren; @@ -60,6 +63,7 @@ public class Game { this.board.loadFromFen(fen); + this.startPosFen = this.board.getFen(); this.movelist = new MoveList(); clock = new Clock(modus); @@ -76,6 +80,8 @@ public class Game { public Game(MoveList movelist) { this.board = new Board(); + this.startPosFen = this.board.getFen(); + this.movelist = movelist; for (Move move : movelist) { @@ -96,6 +102,7 @@ public class Game { this.board.loadFromFen(fen); this.movelist = new MoveList(); + this.startPosFen = this.board.getFen(); // this.sp = new SpielFrame(); // this.clockPlayer1 = new Clock(); @@ -125,18 +132,30 @@ public class Game { this.movelist.removeLast(); } + /** + * Copys the current move list to the savestate + */ public void quicksave() { - logger.info("Quicksaved"); + // TODO: save the current clocktime this.savestate = new MoveList(this.movelist); + logger.info("Quicksaved"); } + /** + * Loads the save state + * + * @brief creates a new board with the startPosFen and then plays all the moves + * from the savestate + */ public void quickload() { - logger.info("Quickloaded"); - this.board = new Board(); + this.board.loadFromFen(startPosFen); + for (Move move : savestate) { this.playMove(move); } + + logger.info("Quickloaded"); } /** diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index ee3f457..e89639e 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -404,6 +404,7 @@ public class SpielFrame extends JFrame { statistik.add(scrollPane); + // TODO: Buttons should be somewhere else JButton quicksave = new JButton(); quicksave.addActionListener(new ButtonQuicksaveListener(this.game)); quicksave.setText("Quicksave"); From 232a4e993690690b9e1ed8c846e7fb632fe35b05 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 15:10:20 +0200 Subject: [PATCH 03/10] fixes bug when no state has be save yet --- .../java/de/mannheim/th/chess/domain/Game.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index c73ce72..b6a1014 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -133,7 +133,7 @@ public class Game { } /** - * Copys the current move list to the savestate + * Copies the current move list to the savestate */ public void quicksave() { // TODO: save the current clocktime @@ -148,14 +148,17 @@ public class Game { * from the savestate */ public void quickload() { - this.board = new Board(); - this.board.loadFromFen(startPosFen); + if (this.savestate != null) { - for (Move move : savestate) { - this.playMove(move); + this.board = new Board(); + this.board.loadFromFen(startPosFen); + + for (Move move : savestate) { + this.playMove(move); + } + + logger.info("Quickloaded"); } - - logger.info("Quickloaded"); } /** From 0806be66e7cd13a38327ead3cabf95eaae8ac1e1 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 15:26:33 +0200 Subject: [PATCH 04/10] fix movelist --- .../de/mannheim/th/chess/controller/ButtonQuickloadListener.java | 1 + src/main/java/de/mannheim/th/chess/domain/Game.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java index c1cf05b..5c5d3a9 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java @@ -20,5 +20,6 @@ public class ButtonQuickloadListener implements ActionListener { public void actionPerformed(ActionEvent e) { this.game.quickload(); this.sf.erstelleBrett(); + this.sf.aktualisiereAusgabe(); } } diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index b6a1014..07fa58f 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -151,6 +151,7 @@ public class Game { if (this.savestate != null) { this.board = new Board(); + this.movelist.clear(); this.board.loadFromFen(startPosFen); for (Move move : savestate) { From 039a5756ee0b8f07496acb22f5d3816bd5f48448 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 17:45:14 +0200 Subject: [PATCH 05/10] add controlpanel --- .../controller/ButtonMovePieceListener.java | 12 +- .../controlPanel/ButtonViewBackListener.java | 22 + .../controlPanel/ButtonViewFirstListener.java | 22 + .../ButtonViewForwardListener.java | 22 + .../controlPanel/ButtonViewLastListener.java | 23 + .../de/mannheim/th/chess/domain/Game.java | 19 +- .../de/mannheim/th/chess/ui/SpielFrame.java | 917 +++++++++--------- 7 files changed, 595 insertions(+), 442 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index 83de36c..35322cf 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -30,19 +30,23 @@ public class ButtonMovePieceListener implements ActionListener { if (this.game.isDraw()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); + this.sf.setViewPointer(this.game.getMoveList().size() - 1); this.sf.showDraw(); } else if (this.game.isMate()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); + this.sf.setViewPointer(this.game.getMoveList().size() - 1); this.sf.showWin(game.getActivePlayer()); + } else { + this.sf.setBoardMode(BoardMode.normal); } - this.sf.setBoardMode(BoardMode.normal); + this.sf.setCursor(null); this.sf.erstelleBrett(); - + if (game.getLastMove() != null) { - - sf.aktualisiereAusgabe(); + + sf.aktualisiereAusgabe(); } } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java new file mode 100644 index 0000000..8d64c5c --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java @@ -0,0 +1,22 @@ +package de.mannheim.th.chess.controller.controlPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; + +public class ButtonViewBackListener implements ActionListener { + private Game game; + + public ButtonViewBackListener(Game game) { + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.setViewPointer(this.game.getViewPointer() - 1); + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java new file mode 100644 index 0000000..2a6777c --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java @@ -0,0 +1,22 @@ +package de.mannheim.th.chess.controller.controlPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; + +public class ButtonViewFirstListener implements ActionListener { + private Game game; + + public ButtonViewFirstListener(Game game) { + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.setViewPointer(0); + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java new file mode 100644 index 0000000..99302a5 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java @@ -0,0 +1,22 @@ +package de.mannheim.th.chess.controller.controlPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; + +public class ButtonViewForwardListener implements ActionListener { + private Game game; + + public ButtonViewForwardListener(Game game) { + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.setViewPointer(this.game.getViewPointer() + 1); + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java new file mode 100644 index 0000000..97f1d82 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java @@ -0,0 +1,23 @@ + +package de.mannheim.th.chess.controller.controlPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import de.mannheim.th.chess.domain.Game; + +public class ButtonViewLastListener implements ActionListener { + private Game game; + + public ButtonViewLastListener(Game game) { + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.game.setViewPointer(this.game.getMoveList().size() - 1); + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index a65305b..85dbf8f 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -34,6 +34,7 @@ public class Game { private boolean rotieren, zuruecknahme; private MoveList movelist; + private int viewPointer; public Game() { @@ -272,11 +273,23 @@ public class Game { return board.getFen(); } -// public Square getSelectedSquare() { -// return this.getSelectedSquare(); -// } + // public Square getSelectedSquare() { + // return this.getSelectedSquare(); + // } public String getUnicodeFromMove(Move move) { return board.getPiece(move.getTo()).getFanSymbol().toUpperCase(); } + + public void setViewPointer(int i) { + this.viewPointer = i; + } + + public int getViewPointer() { + return this.viewPointer; + } + + public void loadView() { + // TODO: add functionality + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 5dcd7b3..356eb4b 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -36,7 +36,8 @@ import javax.swing.JTextArea; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; - +import java.awt.Dimension; +import java.awt.FlowLayout; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -44,492 +45,538 @@ import java.awt.GridLayout; public class SpielFrame extends JFrame { - private static final Logger logger = LogManager.getLogger(App.class); + private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private ArrayList buttons = new ArrayList<>(); - private HashMap belegungen = new HashMap<>(); - private JPanel panelLinks, panelRechts, contentPane; - private JButton undo, undo2; - private JTextArea ausgabe; - private Game game; - private Clock clock; - private ArrayList anzeigeMoves = new ArrayList(); - - private BoardMode mode; - private Square selectedSquare; - - public enum BoardMode { - normal, pieceSelected, finished - } - - /** - * Create the frame. - */ - public SpielFrame(Game game) { - - this.game = game; - this.clock = game.getClock(); - this.clock.start(); - - mode = BoardMode.normal; - - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 1920, 1080); - setTitle("Schach"); - setAlwaysOnTop(true); - - contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); - setContentPane(contentPane); - - // Linkes Panel mit GridLayout 8x8 für Schachbrett - panelLinks = new JPanel(new GridLayout(8, 8)); - - erstelleBrett(); - - // Rechtes Panel für Steuerung oder zusätzliche Eingaben - panelRechts = new JPanel(); - panelRechts.setBackground(new Color(90, 90, 90)); - panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); - - // Panel für alle Eingaben von Player 2 - panelRechts.add(getUiPlayerTwo()); - - // Panel für Statistikanzeigen - panelRechts.add(getUiStatistik()); - - // Panel für alle Eingaben von Player 1 - panelRechts.add(getUiPlayerOne()); - - // JSplitPane horizontal (linke und rechte Hälfte) - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); - splitPane.setResizeWeight(0.75); - splitPane.setBackground(Color.BLACK); - splitPane.setDividerSize(1); - splitPane.setEnabled(false); - - contentPane.add(splitPane, BorderLayout.CENTER); - - setVisible(true); - } - - /** - * Erstellt alle Buttons und fügt sie dem Frame hinzu. - */ - public void erstelleBrett() { - - this.clearButtons(); - this.setDefaultBackground(); - this.setButtonsActions(); - - ladeBrett(); - - panelLinks.revalidate(); - panelLinks.repaint(); - - } - - private int mirrowedGrid(int i) { - return 63 - (((i / 8) * 8) + (7 - i % 8)); - } - - /** - * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren - */ - private void ladeBrett() { - // System.out.println(game.toFEN()); - - char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); - int i = 0; - for (int j = 0; j < fen.length; j++) { - if (Character.isDigit(fen[j])) { - int leerfelder = Character.getNumericValue(fen[j]); - for (int k = 0; k < leerfelder; k++) { - belegungen.put(buttons.get(i), "n-n"); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder - // nicht ckickbar sein sollten. - i++; - } - continue; - } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also - belegungen.put(buttons.get(i), "w-" + fen[j]); - } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also - belegungen.put(buttons.get(i), "b-" + fen[j]); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß - // beginnen kann - } - buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - - i++; - - } - } - - /** - * Clears the existing buttons from the button list, panellinks and fills them - * with new blank ones. - */ - private void clearButtons() { - - buttons.clear(); - panelLinks.removeAll(); - - for (int i = 0; i < 64; i++) { - JButton b = new JButton(); - - b.setEnabled(false); - - // style - b.setFocusPainted(false); - b.setFont(new Font("Arial", Font.PLAIN, 30)); - b.setForeground(Color.WHITE); - b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - b.setName(i + ""); - - buttons.add(b); - } - } - - /** - * Sets the default background color for the buttons in the grid. - */ - private void setDefaultBackground() { - for (int i = 0; i < 64; i++) { - JButton b = buttons.get(i); - if ((i / 8 + i % 8) % 2 == 0) { - // logger.info("Helles Feld erstellt." + i); - b.setBackground(new Color(90, 90, 90)); - } else { - // logger.info("Dunkles Feld erstellt." + i); - b.setBackground(new Color(65, 65, 65)); - } - } - } - - /* - * Switches the button actions depending on the boardmode - */ - private void setButtonsActions() { - - List selectables; - - switch (this.mode) { - case BoardMode.normal: - - selectables = game.getAllLegalMoveableSquares(); - - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - b.setEnabled(true); - // b.setBackground(Color.green); - b.addActionListener(new ButtonSelectPieceListener(this, square)); - } - - break; - - case BoardMode.pieceSelected: - - JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); - s.setEnabled(true); - s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); - - selectables = game.getLegalMoveableSquares(selectedSquare); - - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - final Move move = new Move(selectedSquare, square); - b.setEnabled(true); - b.setBackground(new Color(230, 100, 100)); - b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); - } - break; - case finished: - clearButtons(); - break; - default: - break; - - } - - for (JButton b : buttons) { - panelLinks.add(b); - } - } - - public void showDraw() { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); - - // JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - // jl.setBounds(50, 30, 200, 25); - // jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - // frame.add(jl); - // frame.setVisible(true); - } - - public void showWin(int player) { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); - - JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); - } - - public int showPromotion() { - final int[] result = { -1 }; - - JDialog dialog = new JDialog(this, "Wähle eine Figur", true); - dialog.setLayout(new GridLayout(2, 2)); - dialog.setSize(300, 200); - - int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; - - for (int i = 0; i < 4; i++) { - int index = (game.getActivePlayer() - 1) * 4 + i; - JButton jb = new JButton(); - jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); - int selectedPiece = index; - jb.addActionListener(e -> { - System.out.println("Test"); - result[0] = selectedPiece; - dialog.dispose(); - }); - dialog.add(jb); - } - - dialog.setLocationRelativeTo(null); - dialog.setVisible(true); - - return result[0]; - } + private static final long serialVersionUID = 1L; + private ArrayList buttons = new ArrayList<>(); + private HashMap belegungen = new HashMap<>(); + private JPanel panelLinks, panelRechts, contentPane, controlPanel; + private JButton undo, undo2; + private JTextArea ausgabe; + private Game game; + private Clock clock; + private ArrayList anzeigeMoves = new ArrayList(); + + private BoardMode mode; + private Square selectedSquare; + + private int viewPointer; + + public enum BoardMode { + normal, pieceSelected, finished + } + + /** + * Create the frame. + */ + public SpielFrame(Game game) { + + this.game = game; + this.clock = game.getClock(); + this.clock.start(); + + mode = BoardMode.normal; + + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 1920, 1080); + setTitle("Schach"); + setAlwaysOnTop(true); + + contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + setContentPane(contentPane); + + // Linkes Panel mit GridLayout 8x8 für Schachbrett + panelLinks = new JPanel(new GridLayout(8, 8)); + + erstelleBrett(); + + // Rechtes Panel für Steuerung oder zusätzliche Eingaben + panelRechts = new JPanel(); + panelRechts.setBackground(new Color(90, 90, 90)); + panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); + + // Panel für alle Eingaben von Player 2 + panelRechts.add(getUiPlayerTwo()); + + panelRechts.add(createControlPanel()); + + // Panel für Statistikanzeigen + panelRechts.add(getUiStatistik()); + + // Panel für alle Eingaben von Player 1 + panelRechts.add(getUiPlayerOne()); + + // JSplitPane horizontal (linke und rechte Hälfte) + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); + splitPane.setResizeWeight(0.75); + splitPane.setBackground(Color.BLACK); + splitPane.setDividerSize(1); + splitPane.setEnabled(false); + + contentPane.add(splitPane, BorderLayout.CENTER); + + setVisible(true); + } + + /** + * Erstellt alle Buttons und fügt sie dem Frame hinzu. + */ + public void erstelleBrett() { + + this.clearButtons(); + this.setDefaultBackground(); + this.setButtonsActions(); + + this.ladeBrett(); + + panelLinks.revalidate(); + panelLinks.repaint(); + + } + + private int mirrowedGrid(int i) { + return 63 - (((i / 8) * 8) + (7 - i % 8)); + } + + /** + * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren + */ + private void ladeBrett() { + // System.out.println(game.toFEN()); + + char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); + int i = 0; + for (int j = 0; j < fen.length; j++) { + if (Character.isDigit(fen[j])) { + int leerfelder = Character.getNumericValue(fen[j]); + for (int k = 0; k < leerfelder; k++) { + belegungen.put(buttons.get(i), "n-n"); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder + // nicht ckickbar sein sollten. + i++; + } + continue; + } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also + belegungen.put(buttons.get(i), "w-" + fen[j]); + } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also + belegungen.put(buttons.get(i), "b-" + fen[j]); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß + // beginnen kann + } + buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + + i++; + + } + } + + /** + * Clears the existing buttons from the button list, panellinks and fills them + * with new blank ones. + */ + private void clearButtons() { + + buttons.clear(); + panelLinks.removeAll(); + + for (int i = 0; i < 64; i++) { + JButton b = new JButton(); + + b.setEnabled(false); + + // style + b.setFocusPainted(false); + b.setFont(new Font("Arial", Font.PLAIN, 30)); + b.setForeground(Color.WHITE); + b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + b.setName(i + ""); + + buttons.add(b); + } + } + + /** + * Sets the default background color for the buttons in the grid. + */ + private void setDefaultBackground() { + for (int i = 0; i < 64; i++) { + JButton b = buttons.get(i); + if ((i / 8 + i % 8) % 2 == 0) { + // logger.info("Helles Feld erstellt." + i); + b.setBackground(new Color(90, 90, 90)); + } else { + // logger.info("Dunkles Feld erstellt." + i); + b.setBackground(new Color(65, 65, 65)); + } + } + } + + /* + * Switches the button actions depending on the boardmode + */ + private void setButtonsActions() { + + List selectables; + + switch (this.mode) { + case BoardMode.normal: + + selectables = game.getAllLegalMoveableSquares(); + + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + b.setEnabled(true); + // b.setBackground(Color.green); + b.addActionListener(new ButtonSelectPieceListener(this, square)); + } + + break; + + case BoardMode.pieceSelected: + + JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); + s.setEnabled(true); + s.setBackground(new Color(165, 42, 42)); + s.addActionListener(new ButtonToNormalListener(this)); + + selectables = game.getLegalMoveableSquares(selectedSquare); + + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + final Move move = new Move(selectedSquare, square); + b.setEnabled(true); + b.setBackground(new Color(230, 100, 100)); + b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); + } + break; + case finished: + // this.enableControlPanelButtons(); + // this.viewPointer = this.game.getMoveList().size() - 1; + break; + default: + break; + + } + + for (JButton b : buttons) { + panelLinks.add(b); + } + } + + public void showDraw() { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + // JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + // jl.setBounds(50, 30, 200, 25); + // jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + // frame.add(jl); + // frame.setVisible(true); + } + + public void showWin(int player) { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); + } + + public int showPromotion() { + final int[] result = { -1 }; + + JDialog dialog = new JDialog(this, "Wähle eine Figur", true); + dialog.setLayout(new GridLayout(2, 2)); + dialog.setSize(300, 200); + + int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; + + for (int i = 0; i < 4; i++) { + int index = (game.getActivePlayer() - 1) * 4 + i; + JButton jb = new JButton(); + jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); + int selectedPiece = index; + jb.addActionListener(e -> { + System.out.println("Test"); + result[0] = selectedPiece; + dialog.dispose(); + }); + dialog.add(jb); + } + + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + + return result[0]; + } + + private JPanel createControlPanel() { + this.controlPanel = new JPanel(); + this.controlPanel.setBackground(new Color(90, 90, 90)); + this.controlPanel.setLayout(new FlowLayout()); + + this.controlPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, controlPanel.getPreferredSize().height)); + + JButton viewFirstButton = new JButton("<<-"); + JButton viewBackButton = new JButton("<-"); + JButton viewForwardButton = new JButton("->"); + JButton viewLastButton = new JButton("->>"); + + viewFirstButton.setEnabled(false); + viewBackButton.setEnabled(false); + viewForwardButton.setEnabled(false); + viewLastButton.setEnabled(false); + + this.controlPanel.add(viewFirstButton); + this.controlPanel.add(viewBackButton); + this.controlPanel.add(viewForwardButton); + this.controlPanel.add(viewLastButton); + + return controlPanel; + } + + private JPanel getUiPlayerTwo() { + + JPanel playerTwo = new JPanel(); + playerTwo.setBackground(new Color(90, 90, 90)); + playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); + + playerTwo.add(Box.createVerticalStrut(15)); + + JLabel pl2 = new JLabel("Player 2:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerTwo.add(pl2); - private JPanel getUiPlayerTwo() { - - JPanel playerTwo = new JPanel(); - playerTwo.setBackground(new Color(90, 90, 90)); - playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); - - playerTwo.add(Box.createVerticalStrut(15)); - - JLabel pl2 = new JLabel("Player 2:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerTwo.add(pl2); - - playerTwo.add(Box.createVerticalStrut(10)); - - JLabel clock1 = clock.getClock2(); - playerTwo.add(clock1); - - playerTwo.add(Box.createVerticalStrut(10)); - - // Button zurücknahme und aufgeben für Player 2 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - - if (game.isZuruecknahme()) { - undo = new JButton("Zug zurücknehmen"); - undo.setBackground(Color.LIGHT_GRAY); - undo.setForeground(Color.BLACK); - undo.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo); + playerTwo.add(Box.createVerticalStrut(10)); + + JLabel clock1 = clock.getClock2(); + playerTwo.add(clock1); - // Button-Listener - undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); - } + playerTwo.add(Box.createVerticalStrut(10)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + // Button zurücknahme und aufgeben für Player 2 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + if (game.isZuruecknahme()) { + undo = new JButton("Zug zurücknehmen"); + undo.setBackground(Color.LIGHT_GRAY); + undo.setForeground(Color.BLACK); + undo.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + // Button-Listener + undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } - aufgebenUndo.add(Box.createHorizontalStrut(10)); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - playerTwo.add(aufgebenUndo); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - playerTwo.add(Box.createVerticalStrut(10)); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - return playerTwo; - } + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - private JPanel getUiStatistik() { + playerTwo.add(aufgebenUndo); - JPanel statistik = new JPanel(); - statistik.setBackground(new Color(90, 90, 90)); - statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); + playerTwo.add(Box.createVerticalStrut(10)); - ausgabe = new JTextArea(); - ausgabe.setEditable(false); - ausgabe.setBackground(new Color(75, 75, 75)); - ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); - ausgabe.setForeground(Color.BLACK); - ausgabe.setText("\n Bisherige Züge:\n"); + return playerTwo; + } - JScrollPane scrollPane = new JScrollPane(ausgabe); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + private JPanel getUiStatistik() { - statistik.add(scrollPane); + JPanel statistik = new JPanel(); + statistik.setBackground(new Color(90, 90, 90)); + statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); - return statistik; - } + ausgabe = new JTextArea(); + ausgabe.setEditable(false); + ausgabe.setBackground(new Color(75, 75, 75)); + ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); + ausgabe.setForeground(Color.BLACK); + ausgabe.setText("\n Bisherige Züge:\n"); - public void aktualisiereAusgabe() { + JScrollPane scrollPane = new JScrollPane(ausgabe); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - StringBuilder sb = new StringBuilder(); - sb.append("\n Bisherige Züge:\n"); + statistik.add(scrollPane); - MoveList l = game.getMoveList(); - anzeigeMoves.add(" " + game.getUnicodeFromMove(l.getLast()) + ": " + l.getLast().toString() + "\n"); + return statistik; + } - for (String line : anzeigeMoves) { - sb.append(line); - } + public void aktualisiereAusgabe() { - ausgabe.setText(sb.toString()); - } + StringBuilder sb = new StringBuilder(); + sb.append("\n Bisherige Züge:\n"); - public void deleteLastAusgabe() { - String[] zeilen = ausgabe.getText().split("\n"); + MoveList l = game.getMoveList(); + anzeigeMoves.add(" " + game.getUnicodeFromMove(l.getLast()) + ": " + l.getLast().toString() + "\n"); - // es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist - if (zeilen.length <= 2) - return; + for (String line : anzeigeMoves) { + sb.append(line); + } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < zeilen.length - 1; i++) { - sb.append(zeilen[i]).append("\n"); - } + ausgabe.setText(sb.toString()); + } - ausgabe.setText(sb.toString()); - } + public void deleteLastAusgabe() { + String[] zeilen = ausgabe.getText().split("\n"); - private JPanel getUiPlayerOne() { + // es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist + if (zeilen.length <= 2) + return; - JPanel playerOne = new JPanel(); - playerOne.setBackground(new Color(90, 90, 90)); - playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < zeilen.length - 1; i++) { + sb.append(zeilen[i]).append("\n"); + } - playerOne.add(Box.createVerticalStrut(10)); + ausgabe.setText(sb.toString()); + } - // Button zurücknahme und aufgeben für Player 1 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + private JPanel getUiPlayerOne() { - if (game.isZuruecknahme()) { - undo2 = new JButton("Zug zurücknehmen"); - undo2.setBackground(Color.LIGHT_GRAY); - undo2.setForeground(Color.BLACK); - undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo2.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo2); + JPanel playerOne = new JPanel(); + playerOne.setBackground(new Color(90, 90, 90)); + playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); - // Button-Listener - undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); + playerOne.add(Box.createVerticalStrut(10)); - } + // Button zurücknahme und aufgeben für Player 1 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + if (game.isZuruecknahme()) { + undo2 = new JButton("Zug zurücknehmen"); + undo2.setBackground(Color.LIGHT_GRAY); + undo2.setForeground(Color.BLACK); + undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo2.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo2); - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + // Button-Listener + undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + } - aufgebenUndo.add(Box.createHorizontalStrut(10)); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - playerOne.add(aufgebenUndo); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - playerOne.add(Box.createVerticalStrut(15)); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - JLabel clock1 = clock.getClock1(); - playerOne.add(clock1); + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - playerOne.add(Box.createVerticalStrut(10)); + playerOne.add(aufgebenUndo); - JLabel pl2 = new JLabel("Player 1:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerOne.add(pl2); + playerOne.add(Box.createVerticalStrut(15)); - return playerOne; - } + JLabel clock1 = clock.getClock1(); + playerOne.add(clock1); - public void setBoardMode(BoardMode bm) { - this.mode = bm; - } + playerOne.add(Box.createVerticalStrut(10)); - public void setSelectedSquare(Square sq) { - this.selectedSquare = sq; - } + JLabel pl2 = new JLabel("Player 1:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerOne.add(pl2); - public HashMap getBelegung() { - return this.belegungen; - } + return playerOne; + } - public JButton getUndo() { - return undo; - } + public void setBoardMode(BoardMode bm) { + this.mode = bm; + } - public JButton getUndo2() { - return undo2; - } + public void setSelectedSquare(Square sq) { + this.selectedSquare = sq; + } - public BoardMode getMode() { - return mode; - } + public HashMap getBelegung() { + return this.belegungen; + } - public Clock getClock() { - return clock; - } + public JButton getUndo() { + return undo; + } + + public JButton getUndo2() { + return undo2; + } + + public BoardMode getMode() { + return mode; + } + + public Clock getClock() { + return clock; + } + + private void enableControlPanelButtons() { + for (Component c : this.controlPanel.getComponents()) { + if (c instanceof JButton) { + c.setEnabled(!c.isEnabled()); + } + } + } + + public void setViewPointer(int i) { + this.viewPointer = i; + } + + public int getViewPointer() { + return this.viewPointer; + } } From b44d2e636f5ba557ad173152934f1f07be00beb9 Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 19:22:43 +0200 Subject: [PATCH 06/10] add view controls --- .../controller/ButtonMovePieceListener.java | 6 +- .../controlPanel/ButtonViewBackListener.java | 14 ++++- .../controlPanel/ButtonViewFirstListener.java | 11 +++- .../ButtonViewForwardListener.java | 14 ++++- .../controlPanel/ButtonViewLastListener.java | 13 +++-- .../de/mannheim/th/chess/domain/Game.java | 6 +- .../de/mannheim/th/chess/ui/SpielFrame.java | 57 +++++++++---------- 7 files changed, 74 insertions(+), 47 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index 35322cf..d22e7fd 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -30,12 +30,14 @@ public class ButtonMovePieceListener implements ActionListener { if (this.game.isDraw()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); - this.sf.setViewPointer(this.game.getMoveList().size() - 1); + this.game.setViewPointer(this.game.getMoveList().size() - 1); + this.sf.enableControlPanelButtons(); this.sf.showDraw(); } else if (this.game.isMate()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); - this.sf.setViewPointer(this.game.getMoveList().size() - 1); + this.game.setViewPointer(this.game.getMoveList().size() - 1); + this.sf.enableControlPanelButtons(); this.sf.showWin(game.getActivePlayer()); } else { this.sf.setBoardMode(BoardMode.normal); diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java index 8d64c5c..b4850c3 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java @@ -4,18 +4,26 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; public class ButtonViewBackListener implements ActionListener { private Game game; + private SpielFrame sf; - public ButtonViewBackListener(Game game) { + public ButtonViewBackListener(Game game, SpielFrame sf) { this.game = game; + this.sf = sf; } @Override public void actionPerformed(ActionEvent e) { - this.game.setViewPointer(this.game.getViewPointer() - 1); - // TODO Auto-generated method stub + if (this.game.getViewPointer() > 0) { + this.game.setViewPointer(this.game.getViewPointer() - 1); + this.game.loadView(); + this.sf.setDefaultButtons(); + this.sf.applyBoardButtons(); + this.sf.ladeBrett(); + } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java index 2a6777c..b13cc66 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java @@ -4,19 +4,24 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; public class ButtonViewFirstListener implements ActionListener { private Game game; + private SpielFrame sf; - public ButtonViewFirstListener(Game game) { + public ButtonViewFirstListener(Game game, SpielFrame sf) { this.game = game; + this.sf = sf; } @Override public void actionPerformed(ActionEvent e) { this.game.setViewPointer(0); - // TODO Auto-generated method stub - + this.game.loadView(); + this.sf.setDefaultButtons(); + this.sf.applyBoardButtons(); + this.sf.ladeBrett(); } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java index 99302a5..82240a8 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java @@ -4,18 +4,26 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; public class ButtonViewForwardListener implements ActionListener { private Game game; + private SpielFrame sf; - public ButtonViewForwardListener(Game game) { + public ButtonViewForwardListener(Game game, SpielFrame sf) { this.game = game; + this.sf = sf; } @Override public void actionPerformed(ActionEvent e) { - this.game.setViewPointer(this.game.getViewPointer() + 1); - // TODO Auto-generated method stub + if (this.game.getMoveList().size() > this.game.getViewPointer()) { + this.game.setViewPointer(this.game.getViewPointer() + 1); + this.game.loadView(); + this.sf.setDefaultButtons(); + this.sf.applyBoardButtons(); + this.sf.ladeBrett(); + } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java index 97f1d82..4c34944 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java @@ -5,19 +5,24 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; public class ButtonViewLastListener implements ActionListener { private Game game; + private SpielFrame sf; - public ButtonViewLastListener(Game game) { + public ButtonViewLastListener(Game game, SpielFrame sf) { this.game = game; + this.sf = sf; } @Override public void actionPerformed(ActionEvent e) { - this.game.setViewPointer(this.game.getMoveList().size() - 1); - // TODO Auto-generated method stub - + this.game.setViewPointer(this.game.getMoveList().size()); + this.game.loadView(); + this.sf.setDefaultButtons(); + this.sf.applyBoardButtons(); + this.sf.ladeBrett(); } } diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index a8725c0..9329aee 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -329,6 +329,10 @@ public class Game { } public void loadView() { - // TODO: add functionality + this.board = new Board(); + this.board.loadFromFen(this.startPosFen); + for (int i = 0; i < this.viewPointer; i++) { + this.board.doMove(this.movelist.get(i)); + } } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index f229230..9b0dd2b 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -14,11 +14,13 @@ import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonAufgebenListener; import de.mannheim.th.chess.controller.ButtonFileSaverListener; import de.mannheim.th.chess.controller.ButtonMovePieceListener; -import de.mannheim.th.chess.controller.ButtonQuickloadListener; -import de.mannheim.th.chess.controller.ButtonQuicksaveListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; import de.mannheim.th.chess.controller.ButtonUndoMoveListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonViewBackListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonViewFirstListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonViewForwardListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonViewLastListener; import java.awt.Font; @@ -62,8 +64,6 @@ public class SpielFrame extends JFrame { private BoardMode mode; private Square selectedSquare; - private int viewPointer; - public enum BoardMode { normal, pieceSelected, finished } @@ -126,15 +126,12 @@ public class SpielFrame extends JFrame { */ public void erstelleBrett() { - this.clearButtons(); - this.setDefaultBackground(); + this.setDefaultButtons(); this.setButtonsActions(); + this.applyBoardButtons(); this.ladeBrett(); - panelLinks.revalidate(); - panelLinks.repaint(); - } private int mirrowedGrid(int i) { @@ -144,7 +141,7 @@ public class SpielFrame extends JFrame { /** * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren */ - private void ladeBrett() { + public void ladeBrett() { // System.out.println(game.toFEN()); char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); @@ -172,6 +169,10 @@ public class SpielFrame extends JFrame { i++; } + + panelLinks.revalidate(); + panelLinks.repaint(); + } /** @@ -215,6 +216,11 @@ public class SpielFrame extends JFrame { } } + public void setDefaultButtons() { + this.clearButtons(); + this.setDefaultBackground(); + } + /* * Switches the button actions depending on the boardmode */ @@ -262,9 +268,6 @@ public class SpielFrame extends JFrame { } - for (JButton b : buttons) { - panelLinks.add(b); - } } public void showDraw() { @@ -338,6 +341,11 @@ public class SpielFrame extends JFrame { viewForwardButton.setEnabled(false); viewLastButton.setEnabled(false); + viewFirstButton.addActionListener(new ButtonViewFirstListener(this.game, this)); + viewBackButton.addActionListener(new ButtonViewBackListener(this.game, this)); + viewForwardButton.addActionListener(new ButtonViewForwardListener(this.game, this)); + viewLastButton.addActionListener(new ButtonViewLastListener(this.game, this)); + this.controlPanel.add(viewFirstButton); this.controlPanel.add(viewBackButton); this.controlPanel.add(viewForwardButton); @@ -435,17 +443,6 @@ public class SpielFrame extends JFrame { statistik.add(scrollPane); - // TODO: Buttons should be somewhere else - JButton quicksave = new JButton(); - quicksave.addActionListener(new ButtonQuicksaveListener(this.game)); - quicksave.setText("Quicksave"); - statistik.add(quicksave); - - JButton quickload = new JButton(); - quickload.addActionListener(new ButtonQuickloadListener(this.game, this)); - quickload.setText("Quickload"); - statistik.add(quickload); - return statistik; } @@ -576,7 +573,7 @@ public class SpielFrame extends JFrame { return clock; } - private void enableControlPanelButtons() { + public void enableControlPanelButtons() { for (Component c : this.controlPanel.getComponents()) { if (c instanceof JButton) { c.setEnabled(!c.isEnabled()); @@ -584,12 +581,10 @@ public class SpielFrame extends JFrame { } } - public void setViewPointer(int i) { - this.viewPointer = i; - } - - public int getViewPointer() { - return this.viewPointer; + public void applyBoardButtons() { + for (JButton b : buttons) { + panelLinks.add(b); + } } } From dc288ee95ef4294bbfd23f558b84493b8766540a Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 19:39:52 +0200 Subject: [PATCH 07/10] add quicksave -load buttons to controlpanel --- src/main/java/de/mannheim/th/chess/ui/SpielFrame.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 9b0dd2b..5d189ad 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -14,6 +14,8 @@ import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonAufgebenListener; import de.mannheim.th.chess.controller.ButtonFileSaverListener; import de.mannheim.th.chess.controller.ButtonMovePieceListener; +import de.mannheim.th.chess.controller.ButtonQuickloadListener; +import de.mannheim.th.chess.controller.ButtonQuicksaveListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; import de.mannheim.th.chess.controller.ButtonUndoMoveListener; @@ -335,21 +337,29 @@ public class SpielFrame extends JFrame { JButton viewBackButton = new JButton("<-"); JButton viewForwardButton = new JButton("->"); JButton viewLastButton = new JButton("->>"); + JButton quicksave = new JButton("Quicksave"); + JButton quickload = new JButton("Quickload"); viewFirstButton.setEnabled(false); viewBackButton.setEnabled(false); viewForwardButton.setEnabled(false); viewLastButton.setEnabled(false); + quicksave.setEnabled(true); + quickload.setEnabled(true); viewFirstButton.addActionListener(new ButtonViewFirstListener(this.game, this)); viewBackButton.addActionListener(new ButtonViewBackListener(this.game, this)); viewForwardButton.addActionListener(new ButtonViewForwardListener(this.game, this)); viewLastButton.addActionListener(new ButtonViewLastListener(this.game, this)); + quicksave.addActionListener(new ButtonQuicksaveListener(this.game)); + quickload.addActionListener(new ButtonQuickloadListener(this.game, this)); + this.controlPanel.add(quicksave); this.controlPanel.add(viewFirstButton); this.controlPanel.add(viewBackButton); this.controlPanel.add(viewForwardButton); this.controlPanel.add(viewLastButton); + this.controlPanel.add(quickload); return controlPanel; } From 2afe8d406cc661516e7a5e3f2f930b919d45175b Mon Sep 17 00:00:00 2001 From: dstuck Date: Tue, 24 Jun 2025 23:47:20 +0200 Subject: [PATCH 08/10] add simple pgn loader --- .../de/mannheim/th/chess/domain/Game.java | 7 +- .../de/mannheim/th/chess/ui/MainFrame.java | 146 +++++++------ .../th/chess/ui/ModeSelectionFrame.java | 198 +++++++++--------- .../mannheim/th/chess/ui/PGNLoaderFrame.java | 100 +++++++++ 4 files changed, 287 insertions(+), 164 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index 9329aee..ca793db 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -16,7 +16,6 @@ import com.github.bhlangonijr.chesslib.move.MoveList; import com.github.bhlangonijr.chesslib.pgn.PgnHolder; import de.mannheim.th.chess.App; -import de.mannheim.th.chess.ui.SpielFrame; import de.mannheim.th.chess.utl.Clock; /** @@ -29,7 +28,6 @@ public class Game { private Board board; private Clock clock; - private SpielFrame sp; private String modus; private boolean rotieren, zuruecknahme; @@ -68,9 +66,6 @@ public class Game { this.movelist = new MoveList(); clock = new Clock(modus); - - sp = new SpielFrame(this); - } /** @@ -89,6 +84,8 @@ public class Game { this.board.doMove(move); } + this.clock = new Clock("blitz"); + // this.clockPlayer1 = new Clock(); // this.clockPlayer2 = new Clock(); } diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index 73c5010..dd69abf 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import de.mannheim.th.chess.App; +import de.mannheim.th.chess.domain.Game; import javax.swing.JLabel; @@ -23,86 +24,109 @@ import java.awt.Font; import java.awt.Color; public class MainFrame extends JFrame { - - private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private JPanel contentPane; + private static final Logger logger = LogManager.getLogger(App.class); - /** - * Create the frame. - */ - public MainFrame() { + private static final long serialVersionUID = 1L; + private JPanel contentPane; + private Game game; - setBackground(Color.LIGHT_GRAY); - setResizable(true); - setAlwaysOnTop(true); - setTitle("Schach"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setBounds(100, 100, 500, 500); + /** + * Create the frame. + */ + public MainFrame() { - contentPane = new JPanel(); - contentPane.setBackground(new Color(90, 90, 90)); - contentPane.setForeground(Color.BLACK); - contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setBackground(Color.LIGHT_GRAY); + setResizable(true); + setAlwaysOnTop(true); + setTitle("Schach"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 500, 500); - setContentPane(contentPane); + contentPane = new JPanel(); + contentPane.setBackground(new Color(90, 90, 90)); + contentPane.setForeground(Color.BLACK); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); - contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + setContentPane(contentPane); - contentPane.add(Box.createVerticalStrut(10)); + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); - JLabel lblNewLabel = new JLabel("Schach"); - lblNewLabel.setForeground(Color.BLACK); - lblNewLabel.setFont(new Font("Serif", Font.BOLD, 60)); - lblNewLabel.setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(lblNewLabel); + contentPane.add(Box.createVerticalStrut(10)); - contentPane.add(Box.createVerticalStrut(10)); + JLabel lblNewLabel = new JLabel("Schach"); + lblNewLabel.setForeground(Color.BLACK); + lblNewLabel.setFont(new Font("Serif", Font.BOLD, 60)); + lblNewLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(lblNewLabel); - JLabel lblNewLabel_1 = new JLabel("by Dominik, Marius und Matias"); - lblNewLabel_1.setFont(new Font("Calibri", Font.ITALIC, 24)); - lblNewLabel_1.setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(lblNewLabel_1); + contentPane.add(Box.createVerticalStrut(10)); - contentPane.add(Box.createVerticalStrut(75)); + JLabel lblNewLabel_1 = new JLabel("by Dominik, Marius und Matias"); + lblNewLabel_1.setFont(new Font("Calibri", Font.ITALIC, 24)); + lblNewLabel_1.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(lblNewLabel_1); - JButton btnNewButton = new JButton("Neues Spiel starten"); - - btnNewButton.setBackground(Color.LIGHT_GRAY); - btnNewButton.setForeground(Color.BLACK); - btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 16)); - btnNewButton.setAlignmentX(Component.CENTER_ALIGNMENT); - btnNewButton.addActionListener(new ActionListener() { + contentPane.add(Box.createVerticalStrut(75)); - @Override - public void actionPerformed(ActionEvent e) { + JButton btnNewButton = new JButton("Neues Spiel starten"); - ModeSelectionFrame ms = new ModeSelectionFrame(); + btnNewButton.setBackground(Color.LIGHT_GRAY); + btnNewButton.setForeground(Color.BLACK); + btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton.setAlignmentX(Component.CENTER_ALIGNMENT); + btnNewButton.addActionListener(new ActionListener() { - } + @Override + public void actionPerformed(ActionEvent e) { + openSelectModeFrame(); + } - }); - contentPane.add(btnNewButton); + }); + contentPane.add(btnNewButton); - contentPane.add(Box.createVerticalStrut(15)); + contentPane.add(Box.createVerticalStrut(15)); - JButton btnNewButton_2 = new JButton("App beenden"); - - btnNewButton_2.setBackground(Color.LIGHT_GRAY); - btnNewButton_2.setForeground(Color.BLACK); - btnNewButton_2.setFont(new Font("Tahoma", Font.BOLD, 16)); - btnNewButton_2.setAlignmentX(Component.CENTER_ALIGNMENT); - btnNewButton_2.addActionListener(new ActionListener() { + JButton pgnLoaderButton = new JButton("Lade aus PGN Datei"); + pgnLoaderButton.addActionListener(e -> openPgnSelectFrame()); + contentPane.add(pgnLoaderButton); - @Override - public void actionPerformed(ActionEvent e) { - System.exit(0); - } + contentPane.add(Box.createVerticalStrut(15)); - }); + JButton btnNewButton_2 = new JButton("App beenden"); - contentPane.add(btnNewButton_2); - setVisible(true); - } + btnNewButton_2.setBackground(Color.LIGHT_GRAY); + btnNewButton_2.setForeground(Color.BLACK); + btnNewButton_2.setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton_2.setAlignmentX(Component.CENTER_ALIGNMENT); + btnNewButton_2.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + + }); + + contentPane.add(btnNewButton_2); + setVisible(true); + } + + public void startGame() { + if (this.game != null) { + SpielFrame sf = new SpielFrame(this.game); + } + } + + public void setGame(Game game) { + this.game = game; + } + + private void openSelectModeFrame() { + ModeSelectionFrame ms = new ModeSelectionFrame(this); + } + + private void openPgnSelectFrame() { + PGNLoaderFrame pf = new PGNLoaderFrame(this); + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java index fb15899..3b19d97 100644 --- a/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java @@ -20,118 +20,120 @@ import de.mannheim.th.chess.controller.ButtonFileLoaderListener; import de.mannheim.th.chess.domain.Game; public class ModeSelectionFrame extends JFrame { - - private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private final JPanel contentPane; - private final ArrayList spiele = new ArrayList<>(); - private String fen; + private static final Logger logger = LogManager.getLogger(App.class); - public ModeSelectionFrame() { - // Frame-Eigenschaften - setTitle("Modusauswahl"); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 500, 500); - setResizable(true); - setAlwaysOnTop(true); + private static final long serialVersionUID = 1L; + private final JPanel contentPane; + private final ArrayList spiele = new ArrayList<>(); + private String fen; - // Panel konfigurieren - contentPane = new JPanel(); - contentPane.setBackground(new Color(90, 90, 90)); - contentPane.setBorder(new EmptyBorder(20, 20, 20, 20)); - contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); - setContentPane(contentPane); + public ModeSelectionFrame(MainFrame mf) { + // Frame-Eigenschaften + setTitle("Modusauswahl"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 500, 500); + setResizable(true); + setAlwaysOnTop(true); - // Überschrift - JLabel jl = new JLabel("Welchen Modus wollen Sie spielen?"); - jl.setFont(new Font("Calibri", Font.BOLD, 20)); - jl.setForeground(Color.BLACK); - jl.setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(jl); - contentPane.add(Box.createVerticalStrut(15)); + // Panel konfigurieren + contentPane = new JPanel(); + contentPane.setBackground(new Color(90, 90, 90)); + contentPane.setBorder(new EmptyBorder(20, 20, 20, 20)); + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + setContentPane(contentPane); - // Modusauswahl - String[] modi = {"Blitz", "Schnellschach", "Klassisch"}; - JComboBox jcb1 = new JComboBox<>(modi); - jcb1 .setMaximumSize(new Dimension(150, 30)); - jcb1 .setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(jcb1 ); - contentPane.add(Box.createVerticalStrut(15)); + // Überschrift + JLabel jl = new JLabel("Welchen Modus wollen Sie spielen?"); + jl.setFont(new Font("Calibri", Font.BOLD, 20)); + jl.setForeground(Color.BLACK); + jl.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl); + contentPane.add(Box.createVerticalStrut(15)); - // Spielbrettdrehen - JLabel jl2 = new JLabel("Soll das Spielbrett nach jedem Zug gedreht werden?"); - jl2 .setFont(new Font("Calibri", Font.BOLD, 20)); - jl2 .setForeground(Color.BLACK); - jl2 .setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(jl2 ); + // Modusauswahl + String[] modi = { "Blitz", "Schnellschach", "Klassisch" }; + JComboBox jcb1 = new JComboBox<>(modi); + jcb1.setMaximumSize(new Dimension(150, 30)); + jcb1.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jcb1); + contentPane.add(Box.createVerticalStrut(15)); - JCheckBox jb1 = new JCheckBox(); - jb1.setOpaque(false); - jb1.setFocusPainted(false); - jb1.setForeground(Color.BLACK); - jb1 .setAlignmentX(Component.CENTER_ALIGNMENT); - jb1 .setMaximumSize(new Dimension(30, 30)); - contentPane.add(jb1 ); - contentPane.add(Box.createVerticalStrut(15)); + // Spielbrettdrehen + JLabel jl2 = new JLabel("Soll das Spielbrett nach jedem Zug gedreht werden?"); + jl2.setFont(new Font("Calibri", Font.BOLD, 20)); + jl2.setForeground(Color.BLACK); + jl2.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl2); - // Zurücknahmeoption - JLabel jl3 = new JLabel("Sollen Zurücknahmen erlaubt sein?"); - jl3.setFont(new Font("Calibri", Font.BOLD, 20)); - jl3.setForeground(Color.BLACK); - jl3.setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(jl3); + JCheckBox jb1 = new JCheckBox(); + jb1.setOpaque(false); + jb1.setFocusPainted(false); + jb1.setForeground(Color.BLACK); + jb1.setAlignmentX(Component.CENTER_ALIGNMENT); + jb1.setMaximumSize(new Dimension(30, 30)); + contentPane.add(jb1); + contentPane.add(Box.createVerticalStrut(15)); - JCheckBox jb2 = new JCheckBox(); - jb2.setOpaque(false); - jb2.setFocusPainted(false); - jb2.setForeground(Color.BLACK); - jb2.setAlignmentX(Component.CENTER_ALIGNMENT); - jb2.setMaximumSize(new Dimension(30, 30)); - contentPane.add(jb2); - - contentPane.add(Box.createVerticalStrut(15)); + // Zurücknahmeoption + JLabel jl3 = new JLabel("Sollen Zurücknahmen erlaubt sein?"); + jl3.setFont(new Font("Calibri", Font.BOLD, 20)); + jl3.setForeground(Color.BLACK); + jl3.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl3); - JButton btnNewButton_1 = new JButton("Vergangenes Spiel laden"); - - btnNewButton_1.setBackground(Color.LIGHT_GRAY); - btnNewButton_1.setForeground(Color.BLACK); - btnNewButton_1.setFont(new Font("Tahoma", Font.BOLD, 16)); - btnNewButton_1.setAlignmentX(Component.CENTER_ALIGNMENT); - btnNewButton_1.addActionListener(new ButtonFileLoaderListener(this)); + JCheckBox jb2 = new JCheckBox(); + jb2.setOpaque(false); + jb2.setFocusPainted(false); + jb2.setForeground(Color.BLACK); + jb2.setAlignmentX(Component.CENTER_ALIGNMENT); + jb2.setMaximumSize(new Dimension(30, 30)); + contentPane.add(jb2); - contentPane.add(btnNewButton_1); - - contentPane.add(Box.createVerticalStrut(25)); + contentPane.add(Box.createVerticalStrut(15)); - // Spiel starten Button - JButton btnNewButton = new JButton("Spiel starten"); - btnNewButton .setBackground(Color.LIGHT_GRAY); - btnNewButton .setForeground(Color.BLACK); - btnNewButton .setFont(new Font("Tahoma", Font.BOLD, 16)); - btnNewButton .setAlignmentX(Component.CENTER_ALIGNMENT); - contentPane.add(btnNewButton ); + JButton btnNewButton_1 = new JButton("Vergangenes Spiel laden"); - // Button-Listener - btnNewButton .addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String modus = (String) jcb1.getSelectedItem(); - boolean rotieren = jb1.isSelected(); - boolean zuruecknahme = jb2.isSelected(); + btnNewButton_1.setBackground(Color.LIGHT_GRAY); + btnNewButton_1.setForeground(Color.BLACK); + btnNewButton_1.setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton_1.setAlignmentX(Component.CENTER_ALIGNMENT); + btnNewButton_1.addActionListener(new ButtonFileLoaderListener(this)); - Game game = new Game(modus, rotieren, zuruecknahme, fen); - - spiele.add(game); + contentPane.add(btnNewButton_1); - dispose(); - } - }); + contentPane.add(Box.createVerticalStrut(25)); - setVisible(true); - } - - public void setFen(String fen) { - this.fen = fen; - } + // Spiel starten Button + JButton btnNewButton = new JButton("Spiel starten"); + btnNewButton.setBackground(Color.LIGHT_GRAY); + btnNewButton.setForeground(Color.BLACK); + btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(btnNewButton); + + // Button-Listener + btnNewButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String modus = (String) jcb1.getSelectedItem(); + boolean rotieren = jb1.isSelected(); + boolean zuruecknahme = jb2.isSelected(); + + Game game = new Game(modus, rotieren, zuruecknahme, fen); + mf.setGame(game); + mf.startGame(); + + // spiele.add(game); + + dispose(); + } + }); + + setVisible(true); + } + + public void setFen(String fen) { + this.fen = fen; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java new file mode 100644 index 0000000..c036047 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java @@ -0,0 +1,100 @@ +package de.mannheim.th.chess.ui; + +import java.util.List; +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +import javax.swing.BoxLayout; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; + +import com.github.bhlangonijr.chesslib.game.Game; +import com.github.bhlangonijr.chesslib.pgn.PgnHolder; + +public class PGNLoaderFrame extends JFrame { + private PgnHolder pgn; + private File selectedFile; + private List games; + private DefaultListModel gameListModel; + private JPanel contentPane; + private JList gameList; + + public PGNLoaderFrame(MainFrame mf) { + setResizable(true); + setAlwaysOnTop(true); + setTitle("Schach"); + setBounds(100, 100, 500, 500); + + contentPane = new JPanel(); + setContentPane(contentPane); + + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + + JButton fileSelectButton = new JButton("Select File"); + fileSelectButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + int returnValue = fileChooser.showOpenDialog(null); + if (returnValue == JFileChooser.APPROVE_OPTION) { + selectedFile = fileChooser.getSelectedFile(); + } + } + }); + contentPane.add(fileSelectButton); + + JButton loadPgnButton = new JButton("Load file"); + loadPgnButton.addActionListener(e -> loadFile()); + contentPane.add(loadPgnButton); + + gameListModel = new DefaultListModel<>(); + + gameList = new JList<>(gameListModel); + gameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + gameList.setVisibleRowCount(5); + + JScrollPane scrollPane = new JScrollPane(gameList); + + contentPane.add(scrollPane); + + JButton startGameButton = new JButton("Starte Spiel"); + startGameButton.addActionListener(e -> { + int index = gameList.getSelectedIndex(); + de.mannheim.th.chess.domain.Game game = new de.mannheim.th.chess.domain.Game(games.get(index).getHalfMoves()); + + mf.setGame(game); + mf.startGame(); + }); + contentPane.add(startGameButton); + + this.setVisible(true); + + } + + private void loadFile() { + if (this.selectedFile != null) { + pgn = new PgnHolder(this.selectedFile.getAbsolutePath()); + try { + pgn.loadPgn(); + games = pgn.getGames(); + int i = 0; + for (Game game : games) { + gameListModel.addElement(i++ + ""); + } + gameList.revalidate(); + } catch (Exception e) { + // TODO: handle exception + } + + } + } + +} From cdf993d9987c55a29e4ba9ce3527db3b3c43cfd7 Mon Sep 17 00:00:00 2001 From: dstuck Date: Wed, 25 Jun 2025 01:46:15 +0200 Subject: [PATCH 09/10] add progessbar --- .../controller/ButtonMovePieceListener.java | 4 +- .../de/mannheim/th/chess/ui/MainFrame.java | 3 + .../mannheim/th/chess/ui/PGNLoaderFrame.java | 59 +++++++++++++++++-- .../de/mannheim/th/chess/ui/SpielFrame.java | 4 ++ 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index d22e7fd..9fd4204 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -27,16 +27,16 @@ public class ButtonMovePieceListener implements ActionListener { else this.game.playMove(this.mv); + this.game.setViewPointer(this.game.getMoveList().size() - 1); + if (this.game.isDraw()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); - this.game.setViewPointer(this.game.getMoveList().size() - 1); this.sf.enableControlPanelButtons(); this.sf.showDraw(); } else if (this.game.isMate()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); - this.game.setViewPointer(this.game.getMoveList().size() - 1); this.sf.enableControlPanelButtons(); this.sf.showWin(game.getActivePlayer()); } else { diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index dd69abf..b3518b6 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -114,7 +114,10 @@ public class MainFrame extends JFrame { public void startGame() { if (this.game != null) { + this.game.stopClock(); SpielFrame sf = new SpielFrame(this.game); + sf.setMode(SpielFrame.BoardMode.finished); + sf.enableControlPanelButtons(); } } diff --git a/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java index c036047..476ae07 100644 --- a/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java @@ -1,7 +1,6 @@ package de.mannheim.th.chess.ui; import java.util.List; -import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; @@ -13,11 +12,14 @@ import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; +import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; +import javax.swing.SwingWorker; import com.github.bhlangonijr.chesslib.game.Game; import com.github.bhlangonijr.chesslib.pgn.PgnHolder; +import com.github.bhlangonijr.chesslib.pgn.PgnLoadListener; public class PGNLoaderFrame extends JFrame { private PgnHolder pgn; @@ -26,11 +28,12 @@ public class PGNLoaderFrame extends JFrame { private DefaultListModel gameListModel; private JPanel contentPane; private JList gameList; + private JProgressBar progressBar; public PGNLoaderFrame(MainFrame mf) { setResizable(true); setAlwaysOnTop(true); - setTitle("Schach"); + setTitle("PGNLoader"); setBounds(100, 100, 500, 500); contentPane = new JPanel(); @@ -65,6 +68,11 @@ public class PGNLoaderFrame extends JFrame { contentPane.add(scrollPane); + progressBar = new JProgressBar(0, 100); + progressBar.setValue(0); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + JButton startGameButton = new JButton("Starte Spiel"); startGameButton.addActionListener(e -> { int index = gameList.getSelectedIndex(); @@ -82,18 +90,57 @@ public class PGNLoaderFrame extends JFrame { private void loadFile() { if (this.selectedFile != null) { pgn = new PgnHolder(this.selectedFile.getAbsolutePath()); + + LoadPGNWorker loadPGNWorker = new LoadPGNWorker(); + loadPGNWorker.addPropertyChangeListener(e -> { + System.out.println(e.getNewValue()); + }); + + progressBar.setIndeterminate(true); + + pgn.getListener().add(loadPGNWorker); + loadPGNWorker.execute(); + + gameList.revalidate(); + } + } + + private class LoadPGNWorker extends SwingWorker implements PgnLoadListener { + + @Override + protected Integer doInBackground() throws Exception { try { pgn.loadPgn(); games = pgn.getGames(); - int i = 0; - for (Game game : games) { - gameListModel.addElement(i++ + ""); + int totalGames = games.size(); + for (int i = 0; i < totalGames; i++) { + publish(i); } - gameList.revalidate(); } catch (Exception e) { // TODO: handle exception } + return pgn.getSize(); + } + @Override + protected void process(List chunks) { + for (Integer index : chunks) { + gameListModel.addElement("Game: " + index); + setProgress(Math.min(90, index * 100 / games.size())); + } + } + + @Override + protected void done() { + setProgress(100); + progressBar.setValue(100); + progressBar.setIndeterminate(false); + } + + @Override + public void notifyProgress(int games) { + setProgress(Math.min(90, games)); + progressBar.setValue(Math.min(90, games)); } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 5d189ad..05c4cc3 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -583,6 +583,10 @@ public class SpielFrame extends JFrame { return clock; } + public void setMode(BoardMode mode) { + this.mode = mode; + } + public void enableControlPanelButtons() { for (Component c : this.controlPanel.getComponents()) { if (c instanceof JButton) { From dc6e6d311ba788924d81d09025141f55f866fc33 Mon Sep 17 00:00:00 2001 From: dstuck Date: Wed, 25 Jun 2025 03:12:46 +0200 Subject: [PATCH 10/10] cleanup --- .../controlPanel/BaseButtonViewListener.java | 24 ++++++++ .../ButtonQuickloadListener.java | 3 +- .../ButtonQuicksaveListener.java | 2 +- .../controlPanel/ButtonViewBackListener.java | 12 +--- .../controlPanel/ButtonViewFirstListener.java | 12 +--- .../ButtonViewForwardListener.java | 12 +--- .../controlPanel/ButtonViewLastListener.java | 12 +--- .../de/mannheim/th/chess/domain/Game.java | 15 +++-- .../de/mannheim/th/chess/ui/MainFrame.java | 23 ++++++- .../mannheim/th/chess/ui/PGNLoaderFrame.java | 45 ++++++++------ .../de/mannheim/th/chess/ui/SpielFrame.java | 60 ++++++++++++------- 11 files changed, 135 insertions(+), 85 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/controller/controlPanel/BaseButtonViewListener.java rename src/main/java/de/mannheim/th/chess/controller/{ => controlPanel}/ButtonQuickloadListener.java (90%) rename src/main/java/de/mannheim/th/chess/controller/{ => controlPanel}/ButtonQuicksaveListener.java (87%) diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/BaseButtonViewListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/BaseButtonViewListener.java new file mode 100644 index 0000000..2fb4c07 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/BaseButtonViewListener.java @@ -0,0 +1,24 @@ +package de.mannheim.th.chess.controller.controlPanel; + +import de.mannheim.th.chess.ui.SpielFrame; +import de.mannheim.th.chess.domain.Game; + +public abstract class BaseButtonViewListener { + protected SpielFrame sf; + protected Game game; + + public BaseButtonViewListener(Game game, SpielFrame sf) { + this.sf = sf; + this.game = game; + } + + /** + * Loads the gamestate and renders the board + */ + protected void updateView() { + this.game.loadView(); + this.sf.setDefaultButtons(); + this.sf.applyBoardButtons(); + this.sf.ladeBrett(); + } +} diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuickloadListener.java similarity index 90% rename from src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java rename to src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuickloadListener.java index 5c5d3a9..996c9ec 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonQuickloadListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuickloadListener.java @@ -1,5 +1,4 @@ - -package de.mannheim.th.chess.controller; +package de.mannheim.th.chess.controller.controlPanel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuicksaveListener.java similarity index 87% rename from src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java rename to src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuicksaveListener.java index c73facc..46fc783 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonQuicksaveListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonQuicksaveListener.java @@ -1,4 +1,4 @@ -package de.mannheim.th.chess.controller; +package de.mannheim.th.chess.controller.controlPanel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java index b4850c3..f0ba8dc 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewBackListener.java @@ -6,23 +6,17 @@ import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.ui.SpielFrame; -public class ButtonViewBackListener implements ActionListener { - private Game game; - private SpielFrame sf; +public class ButtonViewBackListener extends BaseButtonViewListener implements ActionListener { public ButtonViewBackListener(Game game, SpielFrame sf) { - this.game = game; - this.sf = sf; + super(game, sf); } @Override public void actionPerformed(ActionEvent e) { if (this.game.getViewPointer() > 0) { this.game.setViewPointer(this.game.getViewPointer() - 1); - this.game.loadView(); - this.sf.setDefaultButtons(); - this.sf.applyBoardButtons(); - this.sf.ladeBrett(); + updateView(); } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java index b13cc66..0353679 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewFirstListener.java @@ -6,22 +6,16 @@ import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.ui.SpielFrame; -public class ButtonViewFirstListener implements ActionListener { - private Game game; - private SpielFrame sf; +public class ButtonViewFirstListener extends BaseButtonViewListener implements ActionListener { public ButtonViewFirstListener(Game game, SpielFrame sf) { - this.game = game; - this.sf = sf; + super(game, sf); } @Override public void actionPerformed(ActionEvent e) { this.game.setViewPointer(0); - this.game.loadView(); - this.sf.setDefaultButtons(); - this.sf.applyBoardButtons(); - this.sf.ladeBrett(); + updateView(); } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java index 82240a8..904d2df 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewForwardListener.java @@ -6,23 +6,17 @@ import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.ui.SpielFrame; -public class ButtonViewForwardListener implements ActionListener { - private Game game; - private SpielFrame sf; +public class ButtonViewForwardListener extends BaseButtonViewListener implements ActionListener { public ButtonViewForwardListener(Game game, SpielFrame sf) { - this.game = game; - this.sf = sf; + super(game, sf); } @Override public void actionPerformed(ActionEvent e) { if (this.game.getMoveList().size() > this.game.getViewPointer()) { this.game.setViewPointer(this.game.getViewPointer() + 1); - this.game.loadView(); - this.sf.setDefaultButtons(); - this.sf.applyBoardButtons(); - this.sf.ladeBrett(); + updateView(); } } diff --git a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java index 4c34944..b7ae7c0 100644 --- a/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/controlPanel/ButtonViewLastListener.java @@ -7,22 +7,16 @@ import java.awt.event.ActionListener; import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.ui.SpielFrame; -public class ButtonViewLastListener implements ActionListener { - private Game game; - private SpielFrame sf; +public class ButtonViewLastListener extends BaseButtonViewListener implements ActionListener { public ButtonViewLastListener(Game game, SpielFrame sf) { - this.game = game; - this.sf = sf; + super(game, sf); } @Override public void actionPerformed(ActionEvent e) { this.game.setViewPointer(this.game.getMoveList().size()); - this.game.loadView(); - this.sf.setDefaultButtons(); - this.sf.applyBoardButtons(); - this.sf.ladeBrett(); + updateView(); } } diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index ca793db..d26f6cd 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -77,7 +77,6 @@ public class Game { this.board = new Board(); this.startPosFen = this.board.getFen(); - this.movelist = movelist; for (Move move : movelist) { @@ -85,9 +84,6 @@ public class Game { } this.clock = new Clock("blitz"); - - // this.clockPlayer1 = new Clock(); - // this.clockPlayer2 = new Clock(); } /** @@ -136,7 +132,8 @@ public class Game { public void quicksave() { // TODO: save the current clocktime this.savestate = new MoveList(this.movelist); - logger.info("Quicksaved"); + + logger.info("Quicksaved..."); } /** @@ -156,7 +153,7 @@ public class Game { this.playMove(move); } - logger.info("Quickloaded"); + logger.info("Quickloaded..."); } } @@ -325,6 +322,12 @@ public class Game { return this.viewPointer; } + /** + * Loads the current view + * + * @brief Creates a new gameboard from the start pos and playes moves until it + * reaches the viewPointer + */ public void loadView() { this.board = new Board(); this.board.loadFromFen(this.startPosFen); diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index b3518b6..badb02e 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -112,7 +112,20 @@ public class MainFrame extends JFrame { setVisible(true); } + /** + * Starts the spielframe and game in playmode + */ public void startGame() { + if (this.game != null) { + this.game.stopClock(); + SpielFrame sf = new SpielFrame(this.game); + } + } + + /** + * Starts the spielframe and game in view mode + */ + public void startView() { if (this.game != null) { this.game.stopClock(); SpielFrame sf = new SpielFrame(this.game); @@ -125,11 +138,17 @@ public class MainFrame extends JFrame { this.game = game; } + /** + * opens the selectmodeframe + */ private void openSelectModeFrame() { - ModeSelectionFrame ms = new ModeSelectionFrame(this); + new ModeSelectionFrame(this); } + /** + * Opens the pgnselectorframe + */ private void openPgnSelectFrame() { - PGNLoaderFrame pf = new PGNLoaderFrame(this); + new PGNLoaderFrame(this); } } diff --git a/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java index 476ae07..c038c93 100644 --- a/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/PGNLoaderFrame.java @@ -17,11 +17,17 @@ import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingWorker; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import com.github.bhlangonijr.chesslib.game.Game; import com.github.bhlangonijr.chesslib.pgn.PgnHolder; import com.github.bhlangonijr.chesslib.pgn.PgnLoadListener; public class PGNLoaderFrame extends JFrame { + + private static final Logger logger = LogManager.getLogger(PGNLoaderFrame.class); + private PgnHolder pgn; private File selectedFile; private List games; @@ -30,56 +36,61 @@ public class PGNLoaderFrame extends JFrame { private JList gameList; private JProgressBar progressBar; + /** + * Opens the PNGLoaderFrame + */ public PGNLoaderFrame(MainFrame mf) { + + // ----- Style ----- setResizable(true); setAlwaysOnTop(true); setTitle("PGNLoader"); setBounds(100, 100, 500, 500); + // ----- contentPane ----- contentPane = new JPanel(); - setContentPane(contentPane); - contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + setContentPane(contentPane); + + // ----- FileSelector ----- JButton fileSelectButton = new JButton("Select File"); - fileSelectButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fileChooser = new JFileChooser(); - int returnValue = fileChooser.showOpenDialog(null); - if (returnValue == JFileChooser.APPROVE_OPTION) { - selectedFile = fileChooser.getSelectedFile(); - } + fileSelectButton.addActionListener(e -> { + JFileChooser fileChooser = new JFileChooser(); + int returnValue = fileChooser.showOpenDialog(null); + if (returnValue == JFileChooser.APPROVE_OPTION) { + selectedFile = fileChooser.getSelectedFile(); } }); contentPane.add(fileSelectButton); + // ----- LoadButton ----- JButton loadPgnButton = new JButton("Load file"); loadPgnButton.addActionListener(e -> loadFile()); contentPane.add(loadPgnButton); + // ----- SelectionList ----- gameListModel = new DefaultListModel<>(); - gameList = new JList<>(gameListModel); gameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); gameList.setVisibleRowCount(5); - JScrollPane scrollPane = new JScrollPane(gameList); - contentPane.add(scrollPane); + // ----- ProgressBar ----- progressBar = new JProgressBar(0, 100); progressBar.setValue(0); progressBar.setStringPainted(true); contentPane.add(progressBar); + // ----- StartButton ----- JButton startGameButton = new JButton("Starte Spiel"); startGameButton.addActionListener(e -> { int index = gameList.getSelectedIndex(); de.mannheim.th.chess.domain.Game game = new de.mannheim.th.chess.domain.Game(games.get(index).getHalfMoves()); mf.setGame(game); - mf.startGame(); + mf.startView(); }); contentPane.add(startGameButton); @@ -93,11 +104,9 @@ public class PGNLoaderFrame extends JFrame { LoadPGNWorker loadPGNWorker = new LoadPGNWorker(); loadPGNWorker.addPropertyChangeListener(e -> { - System.out.println(e.getNewValue()); + progressBar.setIndeterminate(true); }); - progressBar.setIndeterminate(true); - pgn.getListener().add(loadPGNWorker); loadPGNWorker.execute(); @@ -117,7 +126,7 @@ public class PGNLoaderFrame extends JFrame { publish(i); } } catch (Exception e) { - // TODO: handle exception + logger.info("Could not load pgn file!"); } return pgn.getSize(); } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 05c4cc3..97681e0 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -14,8 +14,8 @@ import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonAufgebenListener; import de.mannheim.th.chess.controller.ButtonFileSaverListener; import de.mannheim.th.chess.controller.ButtonMovePieceListener; -import de.mannheim.th.chess.controller.ButtonQuickloadListener; -import de.mannheim.th.chess.controller.ButtonQuicksaveListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonQuickloadListener; +import de.mannheim.th.chess.controller.controlPanel.ButtonQuicksaveListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; import de.mannheim.th.chess.controller.ButtonUndoMoveListener; @@ -218,6 +218,9 @@ public class SpielFrame extends JFrame { } } + /** + * Sets the to default buttons + */ public void setDefaultButtons() { this.clearButtons(); this.setDefaultBackground(); @@ -326,6 +329,9 @@ public class SpielFrame extends JFrame { return result[0]; } + /** + * Creates the controlPanel and its Buttons + */ private JPanel createControlPanel() { this.controlPanel = new JPanel(); this.controlPanel.setBackground(new Color(90, 90, 90)); @@ -333,32 +339,40 @@ public class SpielFrame extends JFrame { this.controlPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, controlPanel.getPreferredSize().height)); - JButton viewFirstButton = new JButton("<<-"); - JButton viewBackButton = new JButton("<-"); - JButton viewForwardButton = new JButton("->"); - JButton viewLastButton = new JButton("->>"); + // ----- ViewQuicksaveButton ----- JButton quicksave = new JButton("Quicksave"); - JButton quickload = new JButton("Quickload"); - - viewFirstButton.setEnabled(false); - viewBackButton.setEnabled(false); - viewForwardButton.setEnabled(false); - viewLastButton.setEnabled(false); quicksave.setEnabled(true); - quickload.setEnabled(true); - - viewFirstButton.addActionListener(new ButtonViewFirstListener(this.game, this)); - viewBackButton.addActionListener(new ButtonViewBackListener(this.game, this)); - viewForwardButton.addActionListener(new ButtonViewForwardListener(this.game, this)); - viewLastButton.addActionListener(new ButtonViewLastListener(this.game, this)); quicksave.addActionListener(new ButtonQuicksaveListener(this.game)); - quickload.addActionListener(new ButtonQuickloadListener(this.game, this)); - this.controlPanel.add(quicksave); + + // ----- ViewFirstButton ----- + JButton viewFirstButton = new JButton("<<-"); + viewFirstButton.setEnabled(false); + viewFirstButton.addActionListener(new ButtonViewFirstListener(this.game, this)); this.controlPanel.add(viewFirstButton); + + // ----- ViewBackButton ----- + JButton viewBackButton = new JButton("<-"); + viewBackButton.setEnabled(false); + viewBackButton.addActionListener(new ButtonViewBackListener(this.game, this)); this.controlPanel.add(viewBackButton); + + // ----- ViewForwardButton ----- + JButton viewForwardButton = new JButton("->"); + viewForwardButton.setEnabled(false); + viewForwardButton.addActionListener(new ButtonViewForwardListener(this.game, this)); this.controlPanel.add(viewForwardButton); + + // ----- ViewLastButton ----- + JButton viewLastButton = new JButton("->>"); + viewLastButton.setEnabled(false); + viewLastButton.addActionListener(new ButtonViewLastListener(this.game, this)); this.controlPanel.add(viewLastButton); + + // ----- ViewQuickloadButton ----- + JButton quickload = new JButton("Quickload"); + quickload.setEnabled(true); + quickload.addActionListener(new ButtonQuickloadListener(this.game, this)); this.controlPanel.add(quickload); return controlPanel; @@ -587,6 +601,9 @@ public class SpielFrame extends JFrame { this.mode = mode; } + /** + * Inverts the Enabled property of the controlpanelButtons + */ public void enableControlPanelButtons() { for (Component c : this.controlPanel.getComponents()) { if (c instanceof JButton) { @@ -595,6 +612,9 @@ public class SpielFrame extends JFrame { } } + /** + * Adds the buttons to the boardpanel + */ public void applyBoardButtons() { for (JButton b : buttons) { panelLinks.add(b);