Added game tab support
+ GamePane component with the game displaying functionality from MainWindow - Simplified MainWindow, added JTabbedPane with GamePane elements - Adjusted FENDropTarget and MenuBar
This commit is contained in:
parent
20e9c8b36e
commit
b3c2253c45
@ -19,26 +19,27 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class FENDropTarget extends DropTargetAdapter {
|
public class FENDropTarget extends DropTargetAdapter {
|
||||||
|
|
||||||
private MainWindow mainWindow;
|
private GamePane gamePane;
|
||||||
|
|
||||||
public FENDropTarget(MainWindow mainWindow) {
|
public FENDropTarget(GamePane gamePane) {
|
||||||
this.mainWindow = mainWindow;
|
this.gamePane = gamePane;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drop(DropTargetDropEvent evt) {
|
public void drop(DropTargetDropEvent evt) {
|
||||||
try {
|
try {
|
||||||
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
|
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings(
|
||||||
List<File> droppedFiles = (List<File>) evt.getTransferable()
|
"unchecked"
|
||||||
.getTransferData(DataFlavor.javaFileListFlavor);
|
)
|
||||||
|
List<File> droppedFiles = (List<File>) evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
|
||||||
try (BufferedReader br = new BufferedReader(new FileReader(droppedFiles.get(0)))) {
|
try (BufferedReader br = new BufferedReader(new FileReader(droppedFiles.get(0)))) {
|
||||||
mainWindow.getGame().reset();
|
gamePane.getGame().reset();
|
||||||
mainWindow.getGame().getBoard().initFromFEN(br.readLine());
|
gamePane.getGame().getBoard().initFromFEN(br.readLine());
|
||||||
mainWindow.getBoardPane().getBoardComponent().repaint();
|
gamePane.getBoardPane().getBoardComponent().repaint();
|
||||||
mainWindow.getGame()
|
gamePane.getGame()
|
||||||
.getPlayers()
|
.getPlayers()
|
||||||
.get(mainWindow.getGame().getBoard().getLog().getActiveColor())
|
.get(gamePane.getGame().getBoard().getLog().getActiveColor())
|
||||||
.requestMove();
|
.requestMove();
|
||||||
evt.dropComplete(true);
|
evt.dropComplete(true);
|
||||||
}
|
}
|
||||||
|
93
src/dev/kske/chess/ui/GamePane.java
Normal file
93
src/dev/kske/chess/ui/GamePane.java
Normal file
@ -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: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>GamePane.java</strong><br>
|
||||||
|
* Created: <strong>23.08.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,10 @@
|
|||||||
package dev.kske.chess.ui;
|
package dev.kske.chess.ui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.GridLayout;
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.dnd.DropTarget;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JTabbedPane;
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
import dev.kske.chess.board.Piece.Color;
|
|
||||||
import dev.kske.chess.game.Game;
|
|
||||||
import dev.kske.chess.game.NaturalPlayer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>Chess</strong><br>
|
* Project: <strong>Chess</strong><br>
|
||||||
@ -23,22 +14,21 @@ import dev.kske.chess.game.NaturalPlayer;
|
|||||||
*/
|
*/
|
||||||
public class MainWindow {
|
public class MainWindow {
|
||||||
|
|
||||||
private JFrame mframe;
|
private JFrame frame;
|
||||||
private JButton btnRestart, btnSwapColors;
|
private JTabbedPane tabbedPane;
|
||||||
private BoardPane boardPane;
|
|
||||||
private Game game;
|
|
||||||
private Color activeColor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch the application.
|
* Launch the application.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings(
|
||||||
|
"unused"
|
||||||
|
)
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
try {
|
try {
|
||||||
MainWindow window = new MainWindow();
|
new MainWindow();
|
||||||
window.mframe.setVisible(true);
|
} catch (Exception ex) {
|
||||||
} catch (Exception e) {
|
ex.printStackTrace();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -53,67 +43,29 @@ public class MainWindow {
|
|||||||
/**
|
/**
|
||||||
* Initialize the contents of the frame.
|
* Initialize the contents of the frame.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings(
|
|
||||||
"unused"
|
|
||||||
)
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
mframe = new JFrame("Chess by Kai S. K. Engelbart");
|
// Configure frame
|
||||||
mframe.setResizable(false);
|
frame = new JFrame("Chess by Kai S. K. Engelbart");
|
||||||
mframe.setBounds(100, 100, 494, 565);
|
frame.setResizable(false);
|
||||||
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
frame.setBounds(100, 100, 494, 565);
|
||||||
mframe.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/pieces/queen_white.png")));
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/pieces/queen_white.png")));
|
||||||
|
|
||||||
boardPane = new BoardPane();
|
// Add frame content
|
||||||
mframe.getContentPane().add(boardPane, BorderLayout.CENTER);
|
tabbedPane = new JTabbedPane();
|
||||||
|
tabbedPane.add("Game 1", new GamePane());
|
||||||
|
frame.getContentPane().add(tabbedPane);
|
||||||
|
|
||||||
JPanel toolPanel = new JPanel();
|
frame.setJMenuBar(new MenuBar(this));
|
||||||
btnRestart = new JButton("Restart");
|
|
||||||
btnRestart.addActionListener((evt) -> {
|
|
||||||
if (game != null) game.reset();
|
|
||||||
game.start();
|
|
||||||
});
|
|
||||||
|
|
||||||
activeColor = Color.WHITE;
|
// Update position and dimensions
|
||||||
btnSwapColors = new JButton("Play as black");
|
frame.pack();
|
||||||
btnSwapColors.addActionListener((evt) -> {
|
frame.setLocationRelativeTo(null);
|
||||||
game.swapColors();
|
frame.setVisible(true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoardPane getBoardPane() { return boardPane; }
|
/**
|
||||||
|
* @return The currently selected {@link GamePane} component
|
||||||
public Game getGame() { return game; }
|
*/
|
||||||
|
public GamePane getSelectedGamePane() { return (GamePane) tabbedPane.getSelectedComponent(); }
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,10 @@ public class MenuBar extends JMenuBar {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -7221583703531248228L;
|
private static final long serialVersionUID = -7221583703531248228L;
|
||||||
|
|
||||||
private final MainWindow mainWindow;
|
private final MainWindow mainWindow;
|
||||||
private final BoardPane boardPane;
|
|
||||||
|
|
||||||
public MenuBar(MainWindow mainWindow) {
|
public MenuBar(MainWindow mainWindow) {
|
||||||
this.mainWindow = mainWindow;
|
this.mainWindow = mainWindow;
|
||||||
boardPane = mainWindow.getBoardPane();
|
|
||||||
|
|
||||||
initGameMenu();
|
initGameMenu();
|
||||||
initEngineMenu();
|
initEngineMenu();
|
||||||
@ -38,14 +36,15 @@ public class MenuBar extends JMenuBar {
|
|||||||
newGameMenuItem.addActionListener((evt) -> {
|
newGameMenuItem.addActionListener((evt) -> {
|
||||||
GameConfigurationDialog dialog = new GameConfigurationDialog();
|
GameConfigurationDialog dialog = new GameConfigurationDialog();
|
||||||
dialog.setVisible(true);
|
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);
|
gameMenu.add(newGameMenuItem);
|
||||||
|
|
||||||
add(gameMenu);
|
add(gameMenu);
|
||||||
|
|
||||||
// Start a game
|
// Start a game
|
||||||
startGame(new Game(boardPane, "Natural Player", "Natural Player"));
|
startGame(new Game(mainWindow.getSelectedGamePane().getBoardPane(), "Natural Player", "Natural Player"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEngineMenu() {
|
private void initEngineMenu() {
|
||||||
@ -54,8 +53,7 @@ public class MenuBar extends JMenuBar {
|
|||||||
JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
|
JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
|
||||||
addEngineMenuItem.addActionListener((evt) -> {
|
addEngineMenuItem.addActionListener((evt) -> {
|
||||||
String enginePath = JOptionPane.showInputDialog(getParent(),
|
String enginePath = JOptionPane.showInputDialog(getParent(),
|
||||||
"Enter the path to a UCI-compatible chess engine:",
|
"Enter the path to a UCI-compatible chess engine:", "Engine selection",
|
||||||
"Engine selection",
|
|
||||||
JOptionPane.QUESTION_MESSAGE);
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
if (enginePath != null) EngineUtil.addEngine(enginePath);
|
if (enginePath != null) EngineUtil.addEngine(enginePath);
|
||||||
});
|
});
|
||||||
@ -72,27 +70,29 @@ public class MenuBar extends JMenuBar {
|
|||||||
|
|
||||||
// TODO: prevent multiple initializations
|
// TODO: prevent multiple initializations
|
||||||
JMenuItem showLogMenuItem = new JMenuItem("Show move log");
|
JMenuItem showLogMenuItem = new JMenuItem("Show move log");
|
||||||
showLogMenuItem
|
showLogMenuItem.addActionListener(
|
||||||
.addActionListener((evt) -> new LogFrame(mainWindow.getGame().getBoard().getLog()).setVisible(true));
|
(evt) -> new LogFrame(mainWindow.getSelectedGamePane().getGame().getBoard().getLog()).setVisible(true));
|
||||||
toolsMenu.add(showLogMenuItem);
|
toolsMenu.add(showLogMenuItem);
|
||||||
|
|
||||||
JMenuItem exportFENMenuItem = new JMenuItem("Export board to FEN");
|
JMenuItem exportFENMenuItem = new JMenuItem("Export board to FEN");
|
||||||
exportFENMenuItem.addActionListener((evt) -> Toolkit.getDefaultToolkit()
|
exportFENMenuItem.addActionListener((evt) -> Toolkit.getDefaultToolkit()
|
||||||
.getSystemClipboard()
|
.getSystemClipboard()
|
||||||
.setContents(new StringSelection(mainWindow.getGame().getBoard().toFEN()), null));
|
.setContents(new StringSelection(mainWindow.getSelectedGamePane().getGame().getBoard().toFEN()), null));
|
||||||
toolsMenu.add(exportFENMenuItem);
|
toolsMenu.add(exportFENMenuItem);
|
||||||
|
|
||||||
// TODO: Synchronize with game
|
// TODO: Synchronize with game
|
||||||
JMenuItem loadFromFENMenuItem = new JMenuItem("Load board from FEN");
|
JMenuItem loadFromFENMenuItem = new JMenuItem("Load board from FEN");
|
||||||
loadFromFENMenuItem.addActionListener((evt) -> {
|
loadFromFENMenuItem.addActionListener((evt) -> {
|
||||||
mainWindow.getGame().reset();
|
mainWindow.getSelectedGamePane().getGame().reset();
|
||||||
mainWindow.getGame()
|
mainWindow.getSelectedGamePane()
|
||||||
.getBoard()
|
.getGame()
|
||||||
|
.getBoard()
|
||||||
.initFromFEN(JOptionPane.showInputDialog("Enter a FEN string: "));
|
.initFromFEN(JOptionPane.showInputDialog("Enter a FEN string: "));
|
||||||
mainWindow.getBoardPane().getBoardComponent().repaint();
|
mainWindow.getSelectedGamePane().getBoardPane().getBoardComponent().repaint();
|
||||||
mainWindow.getGame()
|
mainWindow.getSelectedGamePane()
|
||||||
|
.getGame()
|
||||||
.getPlayers()
|
.getPlayers()
|
||||||
.get(mainWindow.getGame().getBoard().getLog().getActiveColor())
|
.get(mainWindow.getSelectedGamePane().getGame().getBoard().getLog().getActiveColor())
|
||||||
.requestMove();
|
.requestMove();
|
||||||
});
|
});
|
||||||
toolsMenu.add(loadFromFENMenuItem);
|
toolsMenu.add(loadFromFENMenuItem);
|
||||||
@ -101,7 +101,7 @@ public class MenuBar extends JMenuBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startGame(Game game) {
|
private void startGame(Game game) {
|
||||||
mainWindow.setGame(game);
|
mainWindow.getSelectedGamePane().setGame(game);
|
||||||
|
|
||||||
// Update board and board component
|
// Update board and board component
|
||||||
game.reset();
|
game.reset();
|
||||||
|
Reference in New Issue
Block a user