From 76fa3859ef162f0421514a0d3c7829d216210729 Mon Sep 17 00:00:00 2001 From: CyB3RC0nN0R Date: Fri, 23 Aug 2019 22:00:30 +0200 Subject: [PATCH] Added game tab support + GamePane component with the game displaying functionality from MainWindow - Simplified MainWindow, added JTabbedPane with GamePane elements - Adjusted FENDropTarget and MenuBar --- src/dev/kske/chess/ui/FENDropTarget.java | 23 ++--- src/dev/kske/chess/ui/GamePane.java | 93 ++++++++++++++++++++ src/dev/kske/chess/ui/MainWindow.java | 104 ++++++----------------- src/dev/kske/chess/ui/MenuBar.java | 36 ++++---- 4 files changed, 151 insertions(+), 105 deletions(-) create mode 100644 src/dev/kske/chess/ui/GamePane.java diff --git a/src/dev/kske/chess/ui/FENDropTarget.java b/src/dev/kske/chess/ui/FENDropTarget.java index 4d01bf5..ccb6526 100644 --- a/src/dev/kske/chess/ui/FENDropTarget.java +++ b/src/dev/kske/chess/ui/FENDropTarget.java @@ -19,26 +19,27 @@ import java.util.List; */ public class FENDropTarget extends DropTargetAdapter { - private MainWindow mainWindow; + private GamePane gamePane; - public FENDropTarget(MainWindow mainWindow) { - this.mainWindow = mainWindow; + public FENDropTarget(GamePane gamePane) { + this.gamePane = gamePane; } @Override public void drop(DropTargetDropEvent evt) { try { evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - @SuppressWarnings("unchecked") - List droppedFiles = (List) evt.getTransferable() - .getTransferData(DataFlavor.javaFileListFlavor); + @SuppressWarnings( + "unchecked" + ) + List droppedFiles = (List) evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); try (BufferedReader br = new BufferedReader(new FileReader(droppedFiles.get(0)))) { - mainWindow.getGame().reset(); - mainWindow.getGame().getBoard().initFromFEN(br.readLine()); - mainWindow.getBoardPane().getBoardComponent().repaint(); - mainWindow.getGame() + gamePane.getGame().reset(); + gamePane.getGame().getBoard().initFromFEN(br.readLine()); + gamePane.getBoardPane().getBoardComponent().repaint(); + gamePane.getGame() .getPlayers() - .get(mainWindow.getGame().getBoard().getLog().getActiveColor()) + .get(gamePane.getGame().getBoard().getLog().getActiveColor()) .requestMove(); evt.dropComplete(true); } diff --git a/src/dev/kske/chess/ui/GamePane.java b/src/dev/kske/chess/ui/GamePane.java new file mode 100644 index 0000000..7dc2bcc --- /dev/null +++ b/src/dev/kske/chess/ui/GamePane.java @@ -0,0 +1,93 @@ +package dev.kske.chess.ui; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.dnd.DropTarget; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import dev.kske.chess.board.Piece.Color; +import dev.kske.chess.game.Game; +import dev.kske.chess.game.NaturalPlayer; + +/** + * Project: Chess
+ * File: GamePane.java
+ * Created: 23.08.2019
+ * Author: Kai S. K. Engelbart + */ +public class GamePane extends JComponent { + + private static final long serialVersionUID = 4349772338239617477L; + + private JButton btnRestart, btnSwapColors; + private BoardPane boardPane; + private Game game; + private Color activeColor; + + @SuppressWarnings( + "unused" + ) + public GamePane() { + setLayout(new BorderLayout()); + boardPane = new BoardPane(); + add(boardPane, BorderLayout.CENTER); + + JPanel toolPanel = new JPanel(); + btnRestart = new JButton("Restart"); + btnRestart.addActionListener((evt) -> { + if (game != null) game.reset(); + game.start(); + }); + + activeColor = Color.WHITE; + btnSwapColors = new JButton("Play as black"); + btnSwapColors.addActionListener((evt) -> { + game.swapColors(); + btnSwapColors.setText("Play as " + activeColor.toString().toLowerCase()); + activeColor = activeColor.opposite(); + }); + + toolPanel.add(btnRestart); + toolPanel.add(btnSwapColors); + add(toolPanel, BorderLayout.NORTH); + + JPanel letterPanel = new JPanel(new GridLayout(1, 8)); + for (int i = 0; i < 8; i++) { + JLabel letterLabel = new JLabel(String.valueOf((char) (65 + i))); + letterLabel.setHorizontalAlignment(JLabel.CENTER); + letterPanel.add(letterLabel); + } + add(letterPanel, BorderLayout.SOUTH); + + JPanel numberPanel = new JPanel(new GridLayout(8, 1)); + for (int i = 0; i < 8; i++) + numberPanel.add(new JLabel(String.valueOf(8 - i))); + add(numberPanel, BorderLayout.EAST); + + new DropTarget(this, new FENDropTarget(this)); + } + + public BoardPane getBoardPane() { return boardPane; } + + /** + * @return The {@link Game} instance associated with this board pane + */ + public Game getGame() { return game; } + + /** + * Assigns a new {@link Game} instance to this game pane. If exactly one of the + * players is natural, color swapping functionality is enabled. + * + * @param game The {@link Game} to assign to this game pane. + */ + public void setGame(Game game) { + if (this.game != null) this.game.disconnect(); + this.game = game; + btnSwapColors.setEnabled(game.getPlayers().get(Color.WHITE) instanceof NaturalPlayer + ^ game.getPlayers().get(Color.BLACK) instanceof NaturalPlayer); + } +} diff --git a/src/dev/kske/chess/ui/MainWindow.java b/src/dev/kske/chess/ui/MainWindow.java index 9fd16a5..bd5b2b4 100644 --- a/src/dev/kske/chess/ui/MainWindow.java +++ b/src/dev/kske/chess/ui/MainWindow.java @@ -1,19 +1,10 @@ package dev.kske.chess.ui; -import java.awt.BorderLayout; import java.awt.EventQueue; -import java.awt.GridLayout; import java.awt.Toolkit; -import java.awt.dnd.DropTarget; -import javax.swing.JButton; import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import dev.kske.chess.board.Piece.Color; -import dev.kske.chess.game.Game; -import dev.kske.chess.game.NaturalPlayer; +import javax.swing.JTabbedPane; /** * Project: Chess
@@ -23,22 +14,21 @@ import dev.kske.chess.game.NaturalPlayer; */ public class MainWindow { - private JFrame mframe; - private JButton btnRestart, btnSwapColors; - private BoardPane boardPane; - private Game game; - private Color activeColor; + private JFrame frame; + private JTabbedPane tabbedPane; /** * Launch the application. */ + @SuppressWarnings( + "unused" + ) public static void main(String[] args) { EventQueue.invokeLater(() -> { try { - MainWindow window = new MainWindow(); - window.mframe.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); + new MainWindow(); + } catch (Exception ex) { + ex.printStackTrace(); } }); } @@ -53,67 +43,29 @@ public class MainWindow { /** * Initialize the contents of the frame. */ - @SuppressWarnings( - "unused" - ) private void initialize() { - mframe = new JFrame("Chess by Kai S. K. Engelbart"); - mframe.setResizable(false); - mframe.setBounds(100, 100, 494, 565); - mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - mframe.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/pieces/queen_white.png"))); + // Configure frame + frame = new JFrame("Chess by Kai S. K. Engelbart"); + frame.setResizable(false); + frame.setBounds(100, 100, 494, 565); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/pieces/queen_white.png"))); - boardPane = new BoardPane(); - mframe.getContentPane().add(boardPane, BorderLayout.CENTER); + // Add frame content + tabbedPane = new JTabbedPane(); + tabbedPane.add("Game 1", new GamePane()); + frame.getContentPane().add(tabbedPane); - JPanel toolPanel = new JPanel(); - btnRestart = new JButton("Restart"); - btnRestart.addActionListener((evt) -> { - if (game != null) game.reset(); - game.start(); - }); + frame.setJMenuBar(new MenuBar(this)); - activeColor = Color.WHITE; - btnSwapColors = new JButton("Play as black"); - btnSwapColors.addActionListener((evt) -> { - game.swapColors(); - btnSwapColors.setText("Play as " + activeColor.toString().toLowerCase()); - activeColor = activeColor.opposite(); - }); - - toolPanel.add(btnRestart); - toolPanel.add(btnSwapColors); - mframe.getContentPane().add(toolPanel, BorderLayout.NORTH); - - JPanel letterPanel = new JPanel(new GridLayout(1, 8)); - for (int i = 0; i < 8; i++) { - JLabel letterLabel = new JLabel(String.valueOf((char) (65 + i))); - letterLabel.setHorizontalAlignment(JLabel.CENTER); - letterPanel.add(letterLabel); - } - mframe.add(letterPanel, BorderLayout.SOUTH); - - JPanel numberPanel = new JPanel(new GridLayout(8, 1)); - for (int i = 0; i < 8; i++) - numberPanel.add(new JLabel(String.valueOf(8 - i))); - mframe.add(numberPanel, BorderLayout.EAST); - - mframe.setJMenuBar(new MenuBar(this)); - - new DropTarget(mframe, new FENDropTarget(this)); - - mframe.pack(); - mframe.setLocationRelativeTo(null); + // Update position and dimensions + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); } - public BoardPane getBoardPane() { return boardPane; } - - public Game getGame() { return game; } - - public void setGame(Game game) { - if (this.game != null) this.game.disconnect(); - this.game = game; - btnSwapColors.setEnabled(game.getPlayers().get(Color.WHITE) instanceof NaturalPlayer - ^ game.getPlayers().get(Color.BLACK) instanceof NaturalPlayer); - } + /** + * @return The currently selected {@link GamePane} component + */ + public GamePane getSelectedGamePane() { return (GamePane) tabbedPane.getSelectedComponent(); } } diff --git a/src/dev/kske/chess/ui/MenuBar.java b/src/dev/kske/chess/ui/MenuBar.java index f2522ea..36c4953 100644 --- a/src/dev/kske/chess/ui/MenuBar.java +++ b/src/dev/kske/chess/ui/MenuBar.java @@ -20,12 +20,10 @@ public class MenuBar extends JMenuBar { private static final long serialVersionUID = -7221583703531248228L; - private final MainWindow mainWindow; - private final BoardPane boardPane; + private final MainWindow mainWindow; public MenuBar(MainWindow mainWindow) { - this.mainWindow = mainWindow; - boardPane = mainWindow.getBoardPane(); + this.mainWindow = mainWindow; initGameMenu(); initEngineMenu(); @@ -38,14 +36,15 @@ public class MenuBar extends JMenuBar { newGameMenuItem.addActionListener((evt) -> { GameConfigurationDialog dialog = new GameConfigurationDialog(); dialog.setVisible(true); - if (dialog.isStartGame()) startGame(new Game(boardPane, dialog.getWhiteName(), dialog.getBlackName())); + if (dialog.isStartGame()) startGame(new Game(mainWindow.getSelectedGamePane().getBoardPane(), + dialog.getWhiteName(), dialog.getBlackName())); }); gameMenu.add(newGameMenuItem); add(gameMenu); // Start a game - startGame(new Game(boardPane, "Natural Player", "Natural Player")); + startGame(new Game(mainWindow.getSelectedGamePane().getBoardPane(), "Natural Player", "Natural Player")); } private void initEngineMenu() { @@ -54,8 +53,7 @@ public class MenuBar extends JMenuBar { JMenuItem addEngineMenuItem = new JMenuItem("Add engine"); addEngineMenuItem.addActionListener((evt) -> { String enginePath = JOptionPane.showInputDialog(getParent(), - "Enter the path to a UCI-compatible chess engine:", - "Engine selection", + "Enter the path to a UCI-compatible chess engine:", "Engine selection", JOptionPane.QUESTION_MESSAGE); if (enginePath != null) EngineUtil.addEngine(enginePath); }); @@ -72,27 +70,29 @@ public class MenuBar extends JMenuBar { // TODO: prevent multiple initializations JMenuItem showLogMenuItem = new JMenuItem("Show move log"); - showLogMenuItem - .addActionListener((evt) -> new LogFrame(mainWindow.getGame().getBoard().getLog()).setVisible(true)); + showLogMenuItem.addActionListener( + (evt) -> new LogFrame(mainWindow.getSelectedGamePane().getGame().getBoard().getLog()).setVisible(true)); toolsMenu.add(showLogMenuItem); JMenuItem exportFENMenuItem = new JMenuItem("Export board to FEN"); exportFENMenuItem.addActionListener((evt) -> Toolkit.getDefaultToolkit() .getSystemClipboard() - .setContents(new StringSelection(mainWindow.getGame().getBoard().toFEN()), null)); + .setContents(new StringSelection(mainWindow.getSelectedGamePane().getGame().getBoard().toFEN()), null)); toolsMenu.add(exportFENMenuItem); // TODO: Synchronize with game JMenuItem loadFromFENMenuItem = new JMenuItem("Load board from FEN"); loadFromFENMenuItem.addActionListener((evt) -> { - mainWindow.getGame().reset(); - mainWindow.getGame() - .getBoard() + mainWindow.getSelectedGamePane().getGame().reset(); + mainWindow.getSelectedGamePane() + .getGame() + .getBoard() .initFromFEN(JOptionPane.showInputDialog("Enter a FEN string: ")); - mainWindow.getBoardPane().getBoardComponent().repaint(); - mainWindow.getGame() + mainWindow.getSelectedGamePane().getBoardPane().getBoardComponent().repaint(); + mainWindow.getSelectedGamePane() + .getGame() .getPlayers() - .get(mainWindow.getGame().getBoard().getLog().getActiveColor()) + .get(mainWindow.getSelectedGamePane().getGame().getBoard().getLog().getActiveColor()) .requestMove(); }); toolsMenu.add(loadFromFENMenuItem); @@ -101,7 +101,7 @@ public class MenuBar extends JMenuBar { } private void startGame(Game game) { - mainWindow.setGame(game); + mainWindow.getSelectedGamePane().setGame(game); // Update board and board component game.reset();