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:
		| @@ -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); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,11 +21,9 @@ 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() | ||||||
|  | 				.getGame() | ||||||
| 				.getBoard() | 				.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